Saj*_*Saj 6 mysql database database-administration
我们有一个使用 MySQL 数据库的在线系统。我们需要将旧的备份数据库(完整表,而不是转储文件)与当前数据库合并。在没有经历任何服务器停机的情况下,你会怎么做?请注意,系统 24/7 全天候在线。可能会出现哪些问题?
谢谢你。
当弄乱 MySQL 的文件系统时,您必须停止 MySQL 服务器。为避免在您的实时机器上停机,请使用具有相同版本的 MySQL 服务器的备份/虚拟机。当BACKUP MySQL 服务器停止时,将表(我假设是 .FRM、.MYI 等?)复制到 /var/lib/mysql/BACKUP_DB(BACKUP_DB 的相应目录)中的文件系统中。
启动BACKUP MySQL 服务器并使用脚本或 CLI 确保数据已正确加载。验证后,mysqldump BACKUP_DB 数据库,以便它可以加载到实时服务器中:
mysqldump --extended-insert BACKUP_DB > /root/sql/BACKUP_DB.sql
Run Code Online (Sandbox Code Playgroud)
您现在已将原始备份数据转换为 SQL 语句,这些 SQL 语句可以在不停机的情况下加载到 MySQL 中(与原始数据不同)。移动BACKUP_DB.sql到现场机器。
作为不同的数据库导入BACKUP_DB.sql到您的LIVE MySQL 实例中:
mysql BACKUP_DB < /root/sql/BACKUP_DB.sql
Run Code Online (Sandbox Code Playgroud)
您现在应该将备份数据库作为 BACKUP_DB 加载到 MySQL 中。
现在,依赖于 INSERT IGNORE 或 REPLACE INTO 语句(您是覆盖旧数据还是在索引中“填充空白”?):
mysqldump --no-create-db
--no-create-info --extended-insert --insert-ignore MERGE_SOURCE | mysql BACKUP_DB
Run Code Online (Sandbox Code Playgroud)
或者,对于 REPLACE INTO 操作:
mysqldump --no-create-db --no-create-info --extended-insert MERGE_SOURCE | sed 's/INSERT INTO/REPLACE INTO/g' | mysql BACKUP_DB
Run Code Online (Sandbox Code Playgroud)
或者,不是将输出管道回 MySQL,而是发送到文件并查看 SQL 语句。
mysqldump --no-create-db --no-create-info --extended-insert --insert-ignore MERGE_SOURCE > /root/sql/merge.sql
mysqldump --no-create-db --no-create-info --extended-insert MERGE_SOURCE | sed 's/INSERT INTO/REPLACE INTO/g' > /root/sql/merge.sql
Run Code Online (Sandbox Code Playgroud)
最后,为了避免停机,将第一个数据库转储到第二个:
mysqldump BACKUP_DB | mysql CURRENT_DB
Run Code Online (Sandbox Code Playgroud)
您始终可以先锁定数据库,以防止将数据写入(例如)带有 a 表中的外键的 z 表(已被覆盖):
FLUSH TABLES WITH READ LOCK;
Run Code Online (Sandbox Code Playgroud)
(按照上一步执行转储)
UNLOCK TABLES;
Run Code Online (Sandbox Code Playgroud)
将 FLUSH 命令添加到转储 .sql 文件的开头,然后将 UNLOCK 添加到结尾。
在这种情况下,请务必四重检查您的数据库名称!询问您不确定的任何后续问题,因为这是高风险的数据混合内容。如果可能,在开发服务器上执行(并详细记录)所需的确切步骤,或虚拟化您的测试,或创建小规模测试。只是测试。而且,当然,进行足够的备份以涵盖所有数据丢失的可能性。
小智 5
对于此示例,假设您的数据库名为“zig”,而您备份的数据库名为“zig_backup”。我还将假设您的备份数据库和您的实时数据库具有相同的架构。
我还将假设您的实时数据库正在不断更新,并且您无法“离线”执行合并,然后翻转开关以使合并的副本“实时”。
需要注意的问题是:
更新过程将需要根据首先合并哪些表以及最后合并哪些表进行规划。我的一般倾向是先做繁重的工作(大桌子),然后在小桌子上工作。根据您的数据大小,这可能无关紧要。
合并的过程将是:
最安全的方法是进行全表连接并插入不匹配的行:
for each table in the "live" database:
INSERT INTO zig.$table
SELECT BACKUP.* FROM zig_backup.$table AS BACKUP
LEFT OUTER JOIN zig.$table AS LIVE ON LIVE.ID=BACKUP.ID
WHERE LIVE.ID IS NULL;
Run Code Online (Sandbox Code Playgroud)
当然,这需要了解每个表的主键。直接的“REPLACE”可能不起作用,因为实时数据库中的行可能已更改,并且它们更改的数据将被
要合并丢失的表,请执行以下操作:
\u zig_backup
SHOW TABLES
Run Code Online (Sandbox Code Playgroud)
要获取所有表的列表,并确定该表是否存在于实时数据库中,您可以执行以下操作:
\u zig
SHOW TABLES LIKE 'tablename';
Run Code Online (Sandbox Code Playgroud)
或者,备份数据库中不存在于“实时”数据库中的表可以二进制复制到实时数据库目录中。
最后,处理从“实时”数据库中删除的内容充其量是困难的,尤其是因为您正在合并某些数据由于某种原因而丢失。
| 归档时间: |
|
| 查看次数: |
2455 次 |
| 最近记录: |