我有一个主/从复制设置,其中我在超过 7000 个数据库中使用 InnoDB 和 MyISAM 表,我想将这些表从主数据库复制到从数据库以恢复复制。
两台服务器都运行 Ubuntu 10.04.2 LTS(使用 mysql-server 5.1.41-3ubuntu12 包)。最近我尝试升级 MySQL,希望我遇到的某些错误在新版本中已经解决 - 因此我的从属服务器现在是 Ubuntu 10.10。但是,问题似乎是一样的。
我不想破坏我的主服务器,所以我尝试对整个磁盘进行 LVM 快照,以便我可以通过 rsync 将我的数据和日志目录复制到我的从服务器:
/var/lib/mysql:我的 ibdata1 和 ib_logfile0 以及我的所有 .ibd 和 .frm 文件都存储在这里。我使用了 innodb_file_per_table,因此有很多 .idb 文件。/var/log/mysql
:我保存所有二进制日志的地方
复制后,我重置了权限:
chown mysql.mysql /var/lib/mysql -R
chown mysql.mysql /var/log/mysql -R
我从 /var/lib/mysql 目录中删除了 master.info 和 reply-log.info 文件。(因为对于某些表来说,我的主服务器实际上是另一个主服务器的从属服务器)。
然后我尝试在从服务器上启动 mysql。很快,我开始在 /var/log/mysql.err 中看到大量错误,如下所示:
InnoDB:错误:数据字典中的表空间 ID 为 150238 InnoDB:但是在文件 ./1_107789/email.ibd 中它是 150747!
或者:
InnoDB:错误:尝试添加名称为“./23_4377/link.ibd”的表空间 148302 InnoDB:将表空间缓存到内存中,但表空间 InnoDB:表空间中已存在名称为“./1_68522/open.ibd”的 148302 InnoDB:内存缓存!
然后时不时地:
110207 13:55:45 InnoDB:文件 ../../../storage/innobase/fil/fil0fil.c 第 603 行中线程 2979265392 中的断言失败 InnoDB:断言失败:0 InnoDB:我们故意产生一个内存陷阱。 InnoDB:向 http://bugs.mysql.com 提交详细的错误报告。 InnoDB:如果你反复遇到断言失败或崩溃,即使 InnoDB:mysqld 启动后,可能会出现 InnoDB:InnoDB 表空间损坏。请参阅 InnoDB:http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html InnoDB:关于强制恢复。 110207 13:55:45 — mysqld 收到信号 6; 这可能是因为你遇到了 bug。这个二进制文件也可能 或者它所链接的某个库已损坏或构建不正确, 或配置错误。此错误也可能由硬件故障引起。 我们将尽力收集一些有助于诊断的信息 问题,但既然我们已经崩溃了,肯定出了问题 这可能会失败。 密钥缓冲区大小=16777216 读取缓冲区大小=131072 最大使用连接数=1 最大线程数=10000 线程连接=1 mysqld 可能会使用最多 key_buffer_size + (read_buffer_size + sort_buffer_size) *max_threads = 868418 K 内存字节数 希望没问题;如果不行,请减少等式中的一些变量。 thd:0xbc5a7138 尝试回溯。您可以使用以下信息来查找 mysqld 死机了。如果此后没有看到任何消息,则表示发生了一些问题 大错特错…… 堆栈底部 = 0xb193f13c 线程堆栈 0x30000 /usr/sbin/mysqld(my_print_stacktrace+0x2d) [0xb7638c4d] /usr/sbin/mysqld(handle_segfault+0x494)[0xb7304854] [0xb707f400] /lib/tls/i686/cmov/libc.so.6(中止+0x182) [0xb6d89a82] /usr/sbin/mysqld(+0x477790) [0xb7514790] /usr/sbin/mysqld(+0x47795e) [0xb751495e] /usr/sbin/mysqld(fil_space_get_size+0xdc) [0xb751966c] /usr/sbin/mysqld(buf_read_page+0xad) [0xb75015dd] /usr/sbin/mysqld(buf_page_get_gen+0x331) [0xb74fab21] /usr/sbin/mysqld(btr_get_size+0x190) [0xb75b02b0] /usr/sbin/mysqld(dict_update_statistics_low+0x50)[0xb7503e70] /usr/sbin/mysqld(dict_table_get+0xec) [0xb750682c] /usr/sbin/mysqld(+0x4cde5f) [0xb756ae5f] /usr/sbin/mysqld(row_ins+0x157) [0xb756d3c7] /usr/sbin/mysqld(row_ins_step+0x110) [0xb756d710] /usr/sbin/mysqld(row_insert_for_mysql+0x37e) [0xb75754de] /usr/sbin/mysqld(ha_innobase::write_row(无符号字符*)+0xf9)[0xb74e1299] /usr/sbin/mysqld(handler::ha_write_row(unsigned char*)+0x6d)[0xb7412d3d] /usr/sbin/mysqld(write_record(THD*、st_table*、st_copy_info*)+0x3ba)[0xb7391e2a] /usr/sbin/mysqld(mysql_insert(THD*、TABLE_LIST*、List&、List >&、List&、List&、enum_duplicates、bool)+0x1122) [0xb73967c2] /usr/sbin/mysqld(mysql_execute_command(THD*)+0xc85) [0xb7317c95] /usr/sbin/mysqld(mysql_parse(THD*、char const*、unsigned int、char const**)+0x3ae) [0xb731f45e] /usr/sbin/mysqld(Query_log_event::do_apply_event(Relay_log_info const*,char const*,unsigned int)+0x47d)[0xb73dbe9d] /usr/sbin/mysqld(Query_log_event::do_apply_event(Relay_log_info const*)+0x26)[0xb73dca76] /usr/sbin/mysqld(apply_event_and_update_pos(Log_event*、THD*、Relay_log_info*)+0x137)[0xb7463cc7] /usr/sbin/mysqld(handle_slave_sql+0x1094) [0xb74662e4] /lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0xb706396e] /lib/tls/i686/cmov/libc.so.6(克隆+0x5e) [0xb6e29a4e] 尝试获取一些变量。 一些指针可能无效并导致转储中止...... thd->query 位于 0xb183bdc6 处,是一个无效指针 thd->线程ID=2 thd->killed=NOT_KILLED http://dev.mysql.com/doc/mysql/en/crashing.html 上的手册页包含 这些信息应该可以帮助您找出导致崩溃的原因。
我一直在尝试各种选项,试图理解为什么它认为存在表不匹配。就我而言,应该不存在不匹配,因为我正在复制 ibdata1、innodb 日志文件以及 .ibd。那么为什么它不恢复并继续进行,以便我可以恢复复制?我显然遗漏了一些东西,但我找不到它。
任何线索或建议都值得赞赏。谢谢
答案1
答案2
我认为问题出在我复制数据的方式上。由于我的旧从服务器上已经有一些数据库,所以我使用同步为了节省复制数据的时间:
/usr/bin/rsync -rtlP --inplace --delete /snapshot/var/lib/mysql another.host.com::root/var/lib/
但是由于我添加了 -I 选项,如下所示:
/usr/bin/rsync -rtlPI --inplace --delete /snapshot/var/lib/mysql another.host.com::root/var/lib/
它对我来说很有效。-I(--ignore-times)告诉 rsync“不要跳过大小和时间匹配的文件”。据推测,对文件进行的微小亚秒级更改(不会更改文件大小或文件时间戳)导致了问题。