Резервное копирование MySQL Amazon RDS

Я пытаюсь настроить Replica вне AWS, а master работает на AWS RDS. И я не хочу простоя у моего хозяина. Поэтому я настраиваю свой подчиненный node, и теперь я хочу создать резервную копию текущей базы данных, которая находится на AWS.

mysqldump -h RDS ENDPOINT -u root -p --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 --all-databases > /root/dump.sql

Я тестировал его на своей виртуальной машине, и он работал нормально, но при связывании с RDS он дает мне ошибку

mysqldump: Couldn't execute 'FLUSH TABLES WITH READ LOCK': Access denied for user 'root'@'%' (using password: YES) (1045)

Это потому, что у меня нет привилегий суперпользователя или как я могу исправить эту проблему? Пожалуйста, предложите мне меня.

Ответы

Ответ 1

RDS не позволяет даже главному пользователю привилегию SUPER, и это необходимо для выполнения FLUSH TABLES WITH READ LOCK. (Это несчастливое ограничение RDS).

Сбой сгенерируется с помощью опции --master-data, которая, конечно же, необходима, если вы хотите узнать точные координаты binlog, где начинается резервное копирование. FLUSH TABLES WITH READ LOCK получает глобальную блокировку чтения во всех таблицах, что позволяет mysqldump START TRANSACTION WITH CONSISTENT SNAPSHOT (как и при использовании --single-transaction), а затем SHOW MASTER STATUS для получения координат двоичного журнала, после чего он освобождает глобальную блокировку чтения, потому что она имеет транзакцию, которая сохранит видимые данные в состоянии, соответствующем этой позиции журнала.

RDS нарушает этот механизм, отрицая привилегию SUPER и не предоставляя очевидного способа обхода.

Есть некоторые хакеры, доступные для правильной работы вокруг этого, ни одна из которых не может быть особенно привлекательной:

  • выполните резервное копирование в течение периода низкого трафика. Если координаты binlog не изменились между временем запуска резервной копии и после того, как резервная копия начала записывать данные на выходной файл или на целевой сервер (при условии, что вы использовали --single-transaction), это будет работать, потому что вы знаете, что координаты не менялись пока процесс выполнялся.

  • соблюдайте позицию binlog на главном праве перед началом резервного копирования и используйте эти координаты с помощью CHANGE MASTER TO. Если ваш мастер binlog_format установлен на ROW, тогда это должно сработать, хотя вам, вероятно, придется пропустить несколько первоначальных ошибок, но не должно иметь впоследствии ошибок. Это работает, потому что репликация на основе строк очень детерминирована и остановится, если попытается вставить что-то, что уже есть, или удалить что-то, что уже прошло. Пройдя мимо ошибок, вы будете находиться в истинных координатах binlog, где фактически был создан последовательный моментальный снимок.

  • как в предыдущем пункте, но после восстановления резервной копии попытайтесь определить правильную позицию, используя mysqlbinlog --base64-output=decode-rows --verbose, чтобы прочитать мастер-бит в полученных координатах, проверив ваше новое ведомое устройство, чтобы узнать, какое из событий должен быть уже выполнен до момента создания моментального снимка и с использованием координат, определенных таким образом, чтобы CHANGE MASTER TO.

  • использовать внешний процесс для получения блокировки чтения для каждой таблицы на сервере, которая остановит все записи; обратите внимание, что позиция binlog из SHOW MASTER STATUS перестала увеличиваться, запускать резервную копию и освобождать эти блокировки.

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

Вероятно, самый безопасный вариант - но также, возможно, самый раздражающий, поскольку он не должен быть необходимым, - это начать с создания реплики RDS для чтения вашего RDS-мастера. После того, как он вставлен и синхронизирован с ведущим, вы можете остановить репликацию в реплике RDS, выполнив хранимую процедуру RDS, CALL mysql.rds_stop_replication которая была введена в RDS 5.6.13 и 5.5.33, который не требует привилегии SUPER.

Когда ведомое устройство реплики RDS остановлено, возьмите mysqldump из реплики RDS-чтения, которая теперь будет иметь неизменный набор данных на нем как определенный набор основных координат. Восстановите эту резервную копию на своем подчиненном подчиненном устройстве, а затем используйте основные координаты реплики RDS для чтения от SHOW SLAVE STATUS Exec_Master_Log_Pos и Relay_Master_Log_File в качестве ваших координат CHANGE MASTER TO.

Значение, показанное в Exec_Master_Log_Pos на подчиненном устройстве, начало следующей транзакции или события, которое будет обработано, и что именно там, где нужно запустить новое подчиненное устройство чтение на главном сервере.

Затем вы можете вывести из строя реплику RDS-чтения после того, как ваш внешний ведомый будет запущен и запущен.

Ответ 2

для позиции бинарного RDS вы можете использовать mydumper с --lock-all-tables, он будет использовать LOCK TABLES ... READ только для получения координат binlog, а затем realease вместо FTWRL.

Ответ 3

Спасибо, Майкл, я думаю, что самое правильное решение и рекомендованное AWS выполняют репликацию с использованием прочитанной реплики в качестве источника, как описано здесь.

Имея мастер RDS, RDS читает реплику и экземпляр с MySQL готов, шаги для получения внешнего подчиненного:

  • На главном уровне увеличьте время хранения binlog.

mysql> CALL mysql.rds_set_configuration('binlog retention hours', 12);

  1. При чтении репликации остановки реплики во избежание изменений во время резервного копирования.

mysql> CALL mysql.rds_stop_replication;

  1. В прочитанной реплике аннотируется статус binlog (Master_Log_File и Read_Master_Log_Pos).

mysql> SHOW SLAVE STATUS;

  1. На экземпляре сервера сделайте резервную копию и импортируйте его (использование mydumper, предложенное Max, может ускорить процесс).

mysqldump -h RDS_READ_REPLICA_IP -u root -p YOUR_DATABASE > backup.sql

mysql -u root -p YOUR_DATABASE < backup.sql

  1. В экземпляре сервера установите его как подчиненный RDS-мастер.

mysql> CHANGE MASTER TO MASTER_HOST='RDS_MASTER_IP',MASTER_USER='myrepladmin', MASTER_PASSWORD='pass', MASTER_LOG_FILE='mysql-bin-changelog.313534', MASTER_LOG_POS=1097;

Верните MASTER_LOG_FILE и MASTER_LOG_POS в значения ранее сохраненных файлов Master_Log_File Read_Master_Log_Pos, также вам нужен пользователь в RDS-хозяине, который будет использоваться ведомой репликацией.

mysql> START SLAVE;

  1. В экземпляре сервера проверьте успешность репликации.

mysql> SHOW SLAVE STATUS;

  1. В реплике возобновления реплики RDS. mysql> CALL mysql.rds_start_replication;

Ответ 4

Ответ Майкла чрезвычайно полезен и фокусируется на главном моменте: вы просто не можете предоставлять требуемую привилегию SUPER на RDS, и поэтому вы не можете использовать флаг -master-data, который упростит ситуацию.

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

Многоуровневый подход к репликации работает хорошо и может включать в себя уровни за пределами RDS/VPC, поэтому с помощью этого метода можно реплицировать из "Classic" EC2 в VPC.

Большая часть необходимой функциональности доступна только в более поздних версиях MySQL 5.5 и 5.6, и я настоятельно рекомендую вам запускать ту же версию во всех БД, участвующих в стеке репликации, поэтому вам, возможно, придется обновить свой старый DB перед всем этим, что означает еще больше скуки и репликации и т.д.

Ответ 5

Все изменилось, так как @Michael - ответ sqlbot, или здесь происходит недоразумение (может быть, с моей стороны),

Вы можете использовать COPY для импорта csv файла в rds, по крайней мере, в версии postgres, вам просто нужно использовать FROM STDIN вместо прямого именования файла,
что означает, что вы заканчиваете такие вещи, как:

cat data.csv | psql postgresql://server:5432/mydb -U user -c "COPY \"mytable\" FROM STDIN DELIMITER ',' "