找回密码
 注册
查看: 1470|回复: 1

mysqldump: Got error: 1033: "Incorrect information in file: when using LOCK

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2022-1-10 15:52:55 | 显示全部楼层 |阅读模式
执行导出数据库:
: \: E2 h- p5 P7 ?! i* Mmysqldump -u root -predh3 nova >/root/zhongnan-nova.sql
/ U$ X4 N. P& Q" v( ?( Jmysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES8 o# E' U. p9 g. H
报错了:
. l3 @) |/ G3 V, k" JGot error: 1033:   
0 K# X! M$ P. V( f: hwhen using LOCK TABLES
; c$ b+ m5 P- Z9 c4 V; I  P. O解决方法
授予用户锁表权限即可。
网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。
mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。
导数据库报上面错,添加参数--single-transaction
6 B: b3 o' R9 C) `7 Y* O[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction  >/root/zhongnan-nova.sql
1 I" U  D% F) ?2 P! m& imysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)! _9 N# r- V% @  G
# t2 C3 ~, K$ v5 x) ]# i8 k! t
还是报错::) `7 w. l- s1 O" s
登录到数据库中show
- t0 Q4 [9 `7 t; EMariaDB [nova]> show create table `agent_builds` ;
. i7 D+ X3 q  j  O9 j% oERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'- O& W  Q- M3 x
查看数据结构:
0 B4 }5 \5 Z. Z# g& J# w) tMariaDB [nova]> desc agent_builds;
7 w* X1 @! ?% k3 J& Q( J9 F& Y# {ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'# {6 b9 [% Q$ m4 g8 ]. T3 v5 G8 k& @

& G1 E5 N* o, C# droot@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql
: h5 K0 j$ i: S; u8 z5 fmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)6 c. u6 O8 w6 T, Z0 g& j& u

7 v" j7 m& r" X2 l+ ~, E- a' _) c6 a4 ]8 j( }1 s
今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。
2 B' [& B% V! Q' K% ^   遇到该问题,解决方案如下:
. s4 u" q- H8 y, k4 m) T7 ^" G   在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:. M4 z, w/ f% X0 E. C
  mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp
+ W* F' i9 Z6 z. M- M2 [1 @( k+ }4 j; E, Z2 a
   下面是对事务表使用LOCK TABLES的说明:" v9 B& G. e  Y/ x
      在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES
* u! j' P1 m6 [5 q1 j" `1 \; ]       对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。" [$ P0 `* |1 Y7 Z8 z
      ROLLBACK不会释放MySQL的非事务表锁定。
* {' ?/ f: ~. N1 t       要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。  Q0 T1 x% p5 a) A
       使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。
  S7 q7 w2 t3 l如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。9 o* S) N) g  @- S5 K4 W- t
READ LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。
. l" `( Y7 a( z8 N4 a       当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。
* U  a+ D" d& hmysql> LOCK TABLE t WRITE, t AS t1 WRITE;
3 r' x! v# G% q$ N  Z6 n' \
0 A! N6 T1 `! m0 y* L9 s+ Smysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES
1 Q" i* E! o2 e: d( w, Z: z5 B5 j" |0 T/ }! m1 ?7 O0 s
mysql> INSERT INTO t SELECT * FROM t AS t1;    如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。
; G; `9 `3 Q2 K( N8 H2 }mysql> LOCK TABLE t READ;+ H, n3 P& U; F& r
* L. f6 V; m% m, t5 G* \
mysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。1 J' l( O  K( _1 Y
mysql> LOCK TABLE t AS myalias READ;3 O" _, u' K. W) s. G

* ~5 q, c* D1 Y1 pmysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES' I  k' C6 Y5 H3 a
( |1 y( u. ^6 V* P9 {( p3 v4 k$ M3 G2 S
mysql> SELECT * FROM t AS myalias;
/ H! H5 a# F8 L. F. W/ L0 vWRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。
. c, K/ q: U8 G" ?) |6 _  vLOCK TABLES按照如下方式执行:
& E) d' W; T0 |- f1.    按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。
# M1 l4 M/ J7 `: ]+ I2.    如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。5 e6 D; }/ Y) E. A- w3 S$ Q
3.    一次锁定一个表,直到线程得到所有锁定为止。2 e, h/ T" t+ h/ w- `- J, a# p
该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:
$ o: `% R8 J  s% f如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。
8 Q4 K. G& K: l: r9 I/ _- q1 L您可以安全地使用KILL来结束一个正在等待表锁定的线程。
3 t' ^  C4 [+ L4 E注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。
: p$ \4 f4 d% P, D7 M. S通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:
8 V) {$ |7 x/ y# y. \" b% `        如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。3 x) U  }/ v: C5 g! i: l* E) S( c- D
有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。
) y% B  B1 C$ g* C1 H        如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:$ i( \$ @6 x  q
              mysql> LOCK TABLES trans READ, customer WRITE;·                6 @7 b( J7 k1 o3 g+ p, H
4 I) V- r3 I) X. d1 X
mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·               
+ W# `9 v# \# u" L3 Q! f" c$ K/ @6 T# ^/ t2 \
mysql> UPDATE customer·                    3 [' U! [3 Y7 P, _, l% f+ B9 K
->     SET total_value=sum_from_previous_statement·                  & i# z) b7 X9 T" C+ k! y% b
  ->     WHERE customer_id=some_id;·               
1 V  L$ @3 d! A/ h! K/ L$ Y5 N- N; O  D" z6 ~
mysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。
2 M7 I$ v8 Y  N* B1 F8 [" O通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。) J/ `6 a1 L2 ^  @8 G
通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。
6 u0 `$ O/ ]% ^4 m要了解更多有关锁定规则的说明
( O) @, H2 Z, V0 n您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。
- d' H' R' m; r: Y1 a) e- }注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。' F0 R) c' ^) {5 t2 U# n% @
3 o3 g0 V7 n0 p7 N  s* h
& d9 m5 o* m4 L8 {' r7 E
) q  ?* k* ^: s1 z! C
在一个网站上看到一个解决方法:
7 j" w# A2 [6 G& h/ \1 D1.创建一个暂存鱼眼/坩埚服务器! f- }1 N+ L3 A( L
2.连接到另一个MySQL数据库服务器
# i8 X! a+ z# B' z+ `3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件- z. c8 Y" v$ I5 x
4.重启Fisheye/Crucible生产服务器
1 A$ o! e5 E3 T; ^

) |1 E2 H+ r9 B" _" v/ `$ G
' I) e0 B; o5 a+ f" t& E

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-1-10 16:28:05 | 显示全部楼层
1.创建一个暂存鱼眼/坩埚服务器4 K7 T5 m( h/ n& {
2.连接到另一个MySQL数据库服务器
! o1 R5 t; {0 w7 N% T3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件- K' u$ B- \: L2 z) I, [0 ]
4.重启Fisheye/Crucible生产服务器
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 00:14 , Processed in 0.030474 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表