Какова процедура восстановления инкрементной резервной копии Cassandra, когда у меня есть большое количество файлов в каталоге резервных копий?

Я задаю этот вопрос, поскольку не вижу в DataStax Docs какого-либо конкретного метода.

Я включил резервное копирование после того, как сделал снимок, и теперь вижу, что в каталоге резервных копий около 200 тыс. Файлов. Я не уверен, как лучше их восстановить.

Копирование всех из них в каталог таблицы Keyspace и выполнение nodetool refresh <ks> <tbl> , но я не вижу, чтобы он работал должным образом, и выдает исключение StackOverflow. Есть ли способ обойти это?

Сейчас я использую Xmx 16G. Я вижу несколько ошибок в журналах, как показано ниже. Это что-то такое с параметрами JVM?

ОШИБКА [gbp-cass-49] [Reference-Reaper: 1] 2020-07-29 18:49: 01,704 Ref.java:223 - ОБНАРУЖЕНА УТЕЧКА: ссылка (org.apache.cassandra.utils.concurrent.Ref $ State @ 156d6370) в класс org.apache.cassandra.utils.concurrent.WrappedSharedCloseable$Tidy@464162733: [Память @ [0..80), Память @ [0..a00)] не была выпущена до того, как ссылка была собрана сборщиком мусора

nodetool refresh выдает следующие ошибки в стандартный вывод:

error: null
-- StackTrace --
java.lang.AssertionError
    at org.apache.cassandra.io.util.FileUtils.renameWithConfirm(FileUtils.java:178)
    at org.apache.cassandra.io.util.FileUtils.renameWithConfirm(FileUtils.java:173)
    at org.apache.cassandra.io.sstable.format.SSTableWriter.rename(SSTableWriter.java:273)
    at org.apache.cassandra.db.ColumnFamilyStore.loadNewSSTables(ColumnFamilyStore.java:714)
    at org.apache.cassandra.db.ColumnFamilyStore.loadNewSSTables(ColumnFamilyStore.java:658)
    at org.apache.cassandra.service.StorageService.loadNewSSTables(StorageService.java:4555)
    at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112)
    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46)
    at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237)
    at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138)
    at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:828)
    at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$241(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$177/1629407070.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

person Avis    schedule 30.07.2020    source источник


Ответы (1)


В вашем вопросе действительно недостаточно действенной информации, чтобы дать содержательный ответ, но я постараюсь ответить изо всех сил.

Добавочные резервные копии позволяют выгружать копии данных во внешнее хранилище. Однако, поскольку Cassandra жестко связывает каждую очищенную таблицу памяти с каталогом backups/, ее содержимое может довольно быстро разрастаться, поэтому вам нужно управлять им. Это объяснило бы, почему у вас осталось 200 КБ резервных копий.

Инкрементные резервные копии предназначены для использования вместе со снимками, которые эквивалентны полным резервным копиям в традиционном смысле, который большинство людей думает о резервных копиях. Рассматривайте моментальные снимки как холодные резервные копии, а инкрементные резервные копии - как дельту с момента последнего моментального снимка.

Это означает, что каждый раз, когда вы делаете снимок на узле, вам необходимо очищать инкрементные резервные копии в каталоге backups/. Исходя из этого, при восстановлении инкрементных резервных копий вам необходимо восстановить соответствующий моментальный снимок (также известный как полная резервная копия), а затем применить инкрементальные копии (резервное копирование дельт после моментального снимка).

Чтобы ответить на другие вопросы, которые вы подняли, вам нужно будет объяснить, что вы имели в виду. Я не думаю, что это работает должным образом. Кроме того, каково полное сообщение об ошибке и полная трассировка стека для исключения? Такой уровень детализации необходим для постановки значимого диагноза, но он не работает.

Опубликованную вами ошибку можно проигнорировать. Это просто сообщение о том, что поток Reference-Reaper успешно нашел потерянные ссылки и вернул их в пул. Он действительно должен регистрироваться на уровне INFO, а не ERROR.

Надеюсь, это поможет. Ваше здоровье!

[EDIT] трассировка стека, которую вы отправили мне в своем обновлении, похоже, что у вас проблема с разрешениями файловой системы. C * не может переименовать файлы, поэтому, вероятно, (а) у них неправильный владелец, (б) неправильные разрешения или (в) и то, и другое. Ваше здоровье!

person Erick Ramirez    schedule 31.07.2020
comment
Спасибо за ваш ответ. Я как-то пропустил захват исключения, которое nodetool выбросило на экран. Но обрабатывает ли он 200K файлов, когда я выполняю `` обновление nodetool ‹ks› ‹table› ''. Есть мысли по этому поводу? Я постараюсь воспроизвести и получить исключение, насколько это возможно. - person Avis; 31.07.2020
comment
См. Сообщение об ошибке, отправленное nodetool refresh, и любезно дайте мне знать, что вы думаете о разрешении. - person Avis; 31.07.2020