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

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2022-1-10 15:52:55 | 显示全部楼层 |阅读模式
执行导出数据库:
( V& u9 K. C; ~/ R' \8 Cmysqldump -u root -predh3 nova >/root/zhongnan-nova.sql % h4 A4 ]) w0 T8 x/ x
mysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES
8 e! ~2 w% @  q6 L$ o' ]% q4 Q报错了:
( g) c! d. j, t0 U" O+ O1 i* dGot error: 1033:    " P2 Z( ~- K% V' H9 y
when using LOCK TABLES
7 y9 X; O7 Q* E, ]6 a0 Z解决方法
授予用户锁表权限即可。
网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。
mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。
导数据库报上面错,添加参数--single-transaction 9 Z! o0 J# L' S$ S& L! s
[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction  >/root/zhongnan-nova.sql ) l* s9 V3 Z1 D5 x! [9 V
mysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)* {( B6 i- H. L2 v9 e" d
$ S7 n( m) m9 v, e; g2 o3 |* T, }6 w
还是报错::1 _2 O& J" g  E: \8 E
登录到数据库中show
: Y) B! g0 [' P& V+ Y( wMariaDB [nova]> show create table `agent_builds` ;7 A$ B9 {) f1 u7 b
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm') w9 j) r& {+ t: @0 C; l
查看数据结构:; w7 T$ x0 e9 [' u! u/ }8 ~
MariaDB [nova]> desc agent_builds;
( P5 e' q8 U* n8 z9 s6 O# GERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'
, u, y5 m+ y8 E5 s, Z& T: H' X
9 N2 X2 K0 O8 u: Z' Q8 @. @0 |: A- Rroot@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql + z9 y' t1 T/ o  @
mysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033); s5 g, u! d9 G: J, o! W9 I

# ]5 ?1 O, F7 T- V3 @$ `9 J5 Z; p  z! _) N  B3 B7 }2 p/ g
今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。
( u# V  O1 ~* ?: z   遇到该问题,解决方案如下:8 @4 `; ~3 f! b
   在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:
- [4 ^- S. F8 m1 \1 ^8 b/ F7 \% w' P  mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp
6 ]( j% f4 Q: _+ v1 m7 n3 z$ L
3 ?! O" S" Q4 _! t   下面是对事务表使用LOCK TABLES的说明:
4 `( f/ K! D$ ^! O. J      在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES" s- Z% w7 ~( X4 j+ z; x
       对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。
& O' I& R( w1 G4 K+ k# P! ~      ROLLBACK不会释放MySQL的非事务表锁定。" r/ T/ e, f' ]& W
       要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。% L1 Y0 X: E' ~5 l
       使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。
  I6 u, l6 ?8 }0 y) v6 I如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。
4 X  @5 O1 {6 |READ LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。
) H. c% X4 \- k/ l% n' k3 b) D1 I       当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。
* n' c; [5 `/ F3 G. ^& O, [mysql> LOCK TABLE t WRITE, t AS t1 WRITE;5 r" `2 ?) g4 [6 d( ?. T4 A

" \" _3 q% `) U. P6 T4 E4 }mysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES/ A5 O1 m& M* ?* o& K, c  C
9 X2 x& o0 a1 p
mysql> INSERT INTO t SELECT * FROM t AS t1;    如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。
; z3 X1 N+ A( |mysql> LOCK TABLE t READ;
9 R, g3 @4 \) y  l: A- ]) z# ~& `$ t& s# P
mysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。
7 h3 f7 M8 R1 k; ^1 Gmysql> LOCK TABLE t AS myalias READ;9 u& x" S. R& `3 g- O+ @6 d( i( g

9 a; [* }, G7 z3 a( O+ n9 h1 y: omysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES3 A1 ]  J8 g3 P

! q8 ~" j! c* z+ h# {3 Zmysql> SELECT * FROM t AS myalias;
" }2 a2 ^9 i3 i4 [8 U2 @; VWRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。/ i- k! G% B& Z/ V
LOCK TABLES按照如下方式执行:
; A" _" i' Y$ ]7 l1.    按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。: w7 J) D8 _  }; Y. ]" {1 A
2.    如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。
6 P* g/ _' m/ ^0 l3.    一次锁定一个表,直到线程得到所有锁定为止。
3 {3 ^) E6 I! t0 k) i5 m) H该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:
9 n, L5 G1 A6 e3 X如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。
# P0 a7 F+ t1 u) ]3 s( ^您可以安全地使用KILL来结束一个正在等待表锁定的线程。
' f5 P; L) ]  W2 p' g) Y& \注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。
% d; |  }- \* m1 ?通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:0 g! v3 W# P& Q' l9 n
        如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。
0 \: h. O6 x' C. X4 M# e有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。
% I: n* l1 L+ N8 A        如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:  Q! b, Y$ t" {% c) Z
              mysql> LOCK TABLES trans READ, customer WRITE;·               
, b; c4 X  ~" @" a" K5 Y0 T/ G7 e+ i& w, r# L
mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·               
: C2 N. J: E; ~6 |3 F2 F
, G% o6 X2 _% l- Rmysql> UPDATE customer·                    
) e5 a- R" t# R3 z->     SET total_value=sum_from_previous_statement·                  
, D) A1 [$ v% X  ->     WHERE customer_id=some_id;·                7 ]) c9 O( ?2 K* U) P% Z

* ]" K& ]) F4 @! o* {mysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。
$ Q$ h+ Q3 p6 p# T6 v- b* U通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。
. O4 {" C7 D% j6 u) Q通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。
- C, c  C. q* g3 ]5 C要了解更多有关锁定规则的说明% }/ y( B0 H# N* F/ U' }" F. ]$ R
您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。" a5 v1 p9 }, J+ `; b
注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。
. Q1 s2 \. _6 h7 i: _& @; }, K" Y% x( E

, k6 }7 |6 v" d/ A$ h- p2 g
9 y! X+ U( k, h( p2 t$ U. y在一个网站上看到一个解决方法:7 i0 W0 x& H8 Z4 h+ a4 k# S; ^
1.创建一个暂存鱼眼/坩埚服务器+ r3 x  K' ]4 X  X# T6 ]6 H, U
2.连接到另一个MySQL数据库服务器9 p2 L( q8 m! I  m3 n. s' x# h# v
3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件1 L" I9 U( E6 C2 G  C$ t/ M9 }1 B
4.重启Fisheye/Crucible生产服务器

7 m7 `) s: [) ]: @" l, J9 G7 G$ E# C# r% {2 ^; k$ _

8 S9 h) R+ h$ e" X' |- v

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-1-10 16:28:05 | 显示全部楼层
1.创建一个暂存鱼眼/坩埚服务器: b" i! g' p% i" z) _1 T
2.连接到另一个MySQL数据库服务器
, ~8 i9 P. i1 a3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件
/ ^" L, |4 o8 b& o+ b3 V9 O4.重启Fisheye/Crucible生产服务器
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 02:35 , Processed in 0.019543 second(s), 21 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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