master库损坏如何恢复

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了master库损坏如何恢复相关的知识,希望对你有一定的参考价值。

关于master数据库: master 数据库记录 SQL Server 系统的所有系统级别信息.它记录所有的登录帐户和系统配置设置. master 数据库是这样一个数据库.它记录所有其它的数据库.其中包括数据库文件的位置. master 数据库记录 SQL Server 的初始化信息.它始终有一个可用的最新 master 数据库备份. 也就是说这个数据库损失或丢失的话.你的SQLSERVER根本就没法启动了.那么我们看看正常的修复方法. 一:重建master数据库【SQL Server 2005 】 版本中更改了使用 Setup 命令重新生成 master 数据库的用法。 在"浏览文件夹"对话框中.选择 SQL Server 2000 光盘上或用于安装 SQL Server 2000 的共享网络目录中的 \Data 文件夹.然后单击"确定"按钮. 单击"设置"按钮.在"排序规则设置"对话框中.验证或更改用于 Master 数据库或其它数据库的设置. 最初.显示的是默认排序规则设置.但这些设置有可能与安装期间选择的排序规则不匹配.可以选择与安装期间使用的排序规则相同的设置.也可以选择新的排序规则设置.完成后单击"确定"按钮. 在"重建 Master"对话框中单击"重建"按钮以启动进程. 重建 Master 实用工具重新安装 master 数据库. 说明:若要继续.则可能需要终止正在运行的服务器.按照上述方法执行后.SQL服务能正常启动. 重建数据库后.启动SQL Server服务.用系统数据库的备份恢复数据库.通常恢复顺序为master->msdb->model.恢复master的备份时要注意:必须在single user模式下进行.有以下几种方法: 进入单用户模式: 1:可以在命令行模式下输入sqlservr -c -f -m或者输入sqlservr -m 其中:-c 可以缩短启动时间.SQL Server 不作为Windows NT的服务启动 -f 用最小配置启动SQL Server -m 单用户模式启动SQL Server 2:可以在控制面板-服务-MSSQLServer的启动参数中输入-c -f -m或者输入-m.点击开始 3:还有一种更灵活的启动方法:用存在注册表里的启动参数启动 在MSSQLServer项下添加项SingleUser.具体内容如下所示: HKEY_LOCAL_MACHINE \Software \Microsoft \MSSQLServer \SingleUser \Parameters SQLArg0:REG_SZ:-dC:\MSSQL7\DATA\MASTER.DAT SQLArg1:REG_SZ:-eC:\MSSQL7\LOG\ERRORLOG SQLArg2:REG_SZ:-lC:\MSSQL7\DATA\MASTLOG.DAT SQLArg3:REG_SZ:-m 在命令行下输入SQLServr -c -sSingleUser.注意:必须是在命令行下进入单用户模式后启动 Query Analyzer执行语句: RESTORE DATABASE master form disk=''''c:\(具体的备份文件名) 参考技术A 遇到损坏或者错误的master数据库是最难解决情况之一。
Master数据库包含了SQL Server需要的关键信息。如果master数据库出错,那么SQL Server就不能启动。要在这种情况下还原master数据库,可以按照下面这些步骤来从灾难中恢复过来:
1. 使用\PRogram Files\Microsoft SQL Server\80\Tools\Binn目录下的rebuidm.exe文件重建master数据库。重建master数据库可以使数据库文件完整无缺。为以防万一,经常把数据和日志文件备份到一个单独的目录是个不错的主意。
2. 使用-m参数启动SQL Server,这样可以以单用户模式重新启动SQL Server。
3. 从最近一次已知最好的备份来还原master数据库。
4. 核实master数据库是不是已经成功还原:确认所有数据库都已恢复正常运行。从最近一次已知最好的备份来还原msdb数据库。
5. 以普通模式停止和启动SQL Server。
6. 向生产用户开放数据库。
如果这样做没有效,那么重建master数据库然后附加这个数据库。master数据库出现问题,那么服务器上所有的数据库都会出现问题。
总的来说,恢复时要完成的第一个步骤就是安装一个新的master数据库,使服务器至少能够启动。
参考技术B 正常的恢复修复方法:
重建master数据库。

【SQL Server 2005 】 版本中更改了使用 Setup 命令重新生成 master 数据库的用法。运行 Setup.exe 重新生成、验证和修复 SQL Server 实例,并重新生成系统数据库。此过程通常用于为损坏的 SQL Server 安装重新生成 master 数据库。 该程序位于X:\Program Files\Microsoft SQL Server\90\Setup Bootstrap目录中.

【SQL Server 2000】中运行Rebuildm.exe.该程序位于X:\Program Files\Microsoft SQL Server\80\Tools\Binn 目录中.
1.在"重建 Master"对话框中单击"浏览"按钮。
2.在"浏览文件夹"对话框中.选择 SQL Server 2000 光盘上或用于安装 SQL Server 2000 的共享网络目录中的 \Data 文件夹.然后单击"确定"按钮.
3.单击"设置"按钮.在"排序规则设置"对话框中.验证或更改用于 Master 数据库或其它数据库的设置.
4.最初.显示的是默认排序规则设置.但这些设置有可能与安装期间选择的排序规则不匹配.可以选择与安装期间使用的排序规则相同的设置.也可以选择新的排序规则设置.完成后单击"确定"按钮.
5.在"重建 Master"对话框中单击"重建"按钮以启动进程. 重建 Master 实用工具重新安装 master 数据库.
6.说明:若要继续.则可能需要终止正在运行的服务器.按照上述方法执行后.SQL服务能正常启动.
7.重建数据库后.启动SQL Server服务.用系统数据库的备份恢复数据库.通常恢复顺序为master->msdb->model.恢复master的备份时要注意:必须在single user模式下进行.有以下几种方法:
进入单用户模式:
1)可以在命令行模式下输入sqlservr -c -f -m或者输入sqlservr -m 。
其中:-c 可以缩短启动时间.SQL Server 不作为Windows NT的服务启动 。
-f 用最小配置启动SQL Server
-m 单用户模式启动SQL Server

2)可以在控制面板-服务-MSSQLServer的启动参数中输入-c -f -m或者输入-m.点击开始。

3)还有一种更灵活的启动方法:用存在注册表里的启动参数启动 。
在MSSQLServer项下添加项SingleUser.具体内容如下所示:
HKEY_LOCAL_MACHINE
\Software
\Microsoft
\MSSQLServer
\SingleUser
\Parameters
SQLArg0:REG_SZ:-dC:\MSSQL7\DATA\MASTER.DAT
SQLArg1:REG_SZ:-eC:\MSSQL7\LOG\ERRORLOG
SQLArg2:REG_SZ:-lC:\MSSQL7\DATA\MASTLOG.DAT
SQLArg3:REG_SZ:-m

4)在命令行下输入SQLServr -c -sSingleUser.注意:必须是在命令行下进入单用户模式后启动 Query 。

5)Analyzer执行语句:
RESTORE DATABASE master form disk=''''c:\(具体的备份文件名)。

《叶问》34期,延迟从库加上MASTER_DELAY,主库宕机后如何快速恢复服务

本文首发于「GreatSQL社区」。

当主库宕机后,延迟从库如何才能"取消"主动延迟,以便恢复服务?

问题描述

本问题来自一位群友,他遇到的情况我简单归纳一下:

  • 实例A是主库,B是延迟从库(设置了延迟7200秒)。

  • 当A挂掉后(已无法连接,或无法启动),希望用B提升成主库。

  • 但是在B上执行 change master to MASTER_DELAY=0 后,B上已经保存的7200秒的relay文件也会被清除掉,并尝试再次从A获取binlog,这样会造成7200秒的数据丢失,未能达成目的。

TA想问:在这样的场景下,还有办法让B库尽快跑完这7200秒延迟数据吗,或者正确的办法是什么呢?

问题解决

先回答问题:这个需求是有办法达成的(而且还不只一种方法),最正确的方法也并不麻烦/复杂(看到最后),只不过有些小窍门要注意下。

方法1,修改系统时间

也就是修改B主机的系统时间,将其往后调整超过7200秒,然后重启slave线程,就能让SQL_THREAD继续应用relay log了。所有relay log应用完毕后,再将系统时间修改回来。

# 修改系统时间,增加7200秒
[root@yejr.run]# date -s "`date --date '7200 second'`"

# 重启slave线程
[root@yejr.run](none)>  STOP SLAVE; START SLAVE;

这种方法(潜在)影响很大,可能对其他系统应用有影响,或者MySQL里部分涉及到日期时间的结果也会受到影响,非常不推荐

方法2,自行手动恢复relay log/binlog

当主库(A)宕机后,查看当前slave的状态:

[root@yejr.run](none)> SHOW SLAVE STATUS\\G
...
              Master_Log_File: binlog.000011
          Read_Master_Log_Pos: 2671
               Relay_Log_File: relay-bin.000005
                Relay_Log_Pos: 361
        Relay_Master_Log_File: binlog.000011
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
...
          Exec_Master_Log_Pos: 746
              Relay_Log_Space: 2704
...
        Seconds_Behind_Master: 387
...
                    SQL_Delay: 7200
          SQL_Remaining_Delay: 6814
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event

可以看到这时候有387秒的落后,主动延迟7200秒,还有6814秒之后才能应用最新的relay log。虽然事务有延迟,但其实slave已经把binlog都复制过来了,在relay log里。

          Read_Master_Log_Pos: 2671  <-- 已读取到最新的binlog了,pos = 2671
               Relay_Log_File: relay-bin.000005  <-- 对应的relay log
                Relay_Log_Pos: 361  <-- 对应的relay log pos
...
          Exec_Master_Log_Pos: 746  <-- 但只apply到 pos = 746

现在,只需要手动把这中间的差异数据拿出来apply就可以了。解析relay log,找到对应master binlog pos = 746的位置,或者直接指定realy log pos = 361的位置也可以:

[root@yejr.run]# ls -la relay-bin.*
-rw-r----- 1 mysql mysql  418 Jun 13 13:31 relay-bin.000004
-rw-r----- 1 mysql mysql 2286 Jun 13 13:33 relay-bin.000005
-rw-r----- 1 mysql mysql   58 Jun 13 13:31 relay-bin.index

[root@yejr.run]# mysqlbinlog --base64-output=decode-rows -vvv relay-bin.000005
...
# at 196
#700101  8:00:00 server id 5001  end_log_pos 0 CRC32 0xaf7e0f79         Rotate to binlog.000011  pos: 746
# at 240
#210613 11:26:08 server id 5001  end_log_pos 0 CRC32 0xfa7fd769         Start: binlog v 4, server v 8.0.22-13 created 210613
 11:26:08
# at 361
#210613 13:33:41 server id 5001  end_log_pos 825 CRC32 0xd5161853       GTID    last_committed=1        sequence_number=3
       rbr_only=yes    original_committed_timestamp=1623562421106412   immediate_commit_timestamp=1623562421106412     transaction_length=275
...

确认对应的事务是存在的,接下来就可以利用relay log恢复数据了。

[root@yejr.run]# mysqlbinlog relay-bin.000005 --start-position=361 | mysql -S./mysql.sock -f

当然了,如果此时A主机还可以连接,只是mysqld服务无法启动的话,亦可直接用A主机上的binlog进行恢复。

这种方法需要细心谨慎,手眼配合密切,容易出错,因此也不推荐

方法3,正确理解MASTER_DELAY,一键搞定

前面铺垫了那么多,看起来想要让延迟从库快速恢复好像有点麻烦的样子。

事实上,只要正确理解,一键命令就搞定了。

当主库发生故障宕机后,binlog其实已经都复制到从库并写入成relay log了。当然了,为避免误操作,建议先备份relay log。

接下来的操作很重要,看准了,一定不要做错:

# 只关闭SQL_THREAD,而不是直接关闭整个SLAVE服务
[root@yejr.run](none)> STOP SLAVE SQL_THREAD;

# 修改MASTER_DELAY,使之不再延迟
[root@yejr.run](none)> CHANGE MASTER TO MASTER_DELAY=0;

# 再次启动SQL_THREAD
[root@yejr.run](none)> START SLAVE SQL_THREAD;

主库虽然宕机了,但从库上只有IO_THREAD会报告连接错误,SQL_THREAD还是可以正常工作的。

上述操作的关键点在于,修改 MASTER_DELAY 时并没有先停掉 IO_THREAD,否则会清空所有的relay log,尝试去主库再次拉取

再次启动 SQL_THREAD 之后,从库就会继续应用relay log,待到全部应用完毕后,完成必要的数据校验,即可提成成为新的主库,对外提供服务了。

看,真的挺简单的吧。

现在来验证下:完全停掉SLAVE服务后修改MASTER_DELAY值,再启动SLAVE服务,此时会清空重置relay log

# 主库宕机后,查看SLAVE状态
[root@yejr.run](none)> SHOW SLAVE STATUS\\G
...
              Master_Log_File: binlog.000017
          Read_Master_Log_Pos: 471
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 321
        Relay_Master_Log_File: binlog.000017
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
...
          Exec_Master_Log_Pos: 196
...
        Seconds_Behind_Master: 69
...
                    SQL_Delay: 7200
          SQL_Remaining_Delay: 7132
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
...

# 查看relay log状态
[root@yejr.run]# ls -la relay-bin.*
-rw-r----- 1 mysql mysql 213 Jun 13 15:11 relay-bin.000001
-rw-r----- 1 mysql mysql 596 Jun 13 15:11 relay-bin.000002
-rw-r----- 1 mysql mysql  58 Jun 13 15:11 relay-bin.index

# 关闭SLAVE服务,修改MASTER_DELAY,再启动SLAVE服务
[root@yejr.run](none)> STOP SLAVE; CHANGE MASTER TO MASTER_DELAY=0; START SLAVE;

# 再次查看relay log,发现被清空重置了
[root@yejr.run]# ls -la relay-bin.*
-rw-r----- 1 mysql mysql 156 Jun 13 15:18 relay-bin.000001
-rw-r----- 1 mysql mysql  29 Jun 13 15:18 relay-bin.index

所以,请记住了,当延迟从库要修改延迟设置时,只需重启SQL_THREAD,千万别图省事重启整个SLAVE服务,这样relay log就不会被清空重置了,也就能实现快速恢复并提升为主库。为以防万一,也请务必备份好relay log

因为relay log是由 IO_THREAD 负责的,所以只要 IO_THREAD 不重启,就不会清空重置。看下MySQL文档中关于relay log的说明:

#原文出处 https://dev.mysql.com/doc/refman/8.0/en/replica-logs.html

The replica's relay log, which is written by the replication I/O thread, contains the transactions read from the replication source server's binary log. The transactions in the relay log are applied on the replica by the replication SQL thread. For information about the relay log, see Section 17.2.4.1, “The Relay Log”.

P.S,本文使用的GreatSQL 8.0.22-13,关于这个版本的说明详见 GreatSQL,打造更好的MGR生态

Enjoy MySQL :)

延伸阅读

  • 13.4.2.1 CHANGE MASTER TO Statement, https://dev.mysql.com/doc/refman/8.0/en/change-master-to.html

  • 17.2.4 Relay Log and Replication Metadata Repositories, https://dev.mysql.com/doc/refman/8.0/en/replica-logs.html

  • 17.4.11 Delayed Replication, https://dev.mysql.com/doc/refman/8.0/en/replication-delayed.html


文章推荐:


点击文末“阅读原文”直达「叶问」专栏

以上是关于master库损坏如何恢复的主要内容,如果未能解决你的问题,请参考以下文章

如何恢复损坏的 XML(加密)

移动硬盘显示磁盘结构损坏且无法读取要如何办啊

Delphi TCanvas 对象从 dll 使用后损坏,如何恢复? [关闭]

如何从损坏的 Xampp 中恢复 sql 表

如何在 Apache Camel 中检测损坏/恢复的 JMS 连接?

ibdata1数据库如何恢复?