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

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2022-1-10 15:52:55 | 显示全部楼层 |阅读模式
执行导出数据库:1 v) z: X! u4 }( I
mysqldump -u root -predh3 nova >/root/zhongnan-nova.sql
  p; C, f4 F% X8 E9 umysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES
3 ]+ l' J# ^  F9 h4 x报错了:
* Y+ ~  E' j9 J7 L) {' J; x% AGot error: 1033:    2 s' E" X. \7 e% \# e4 P
when using LOCK TABLES- a  q, z* ?$ f  F( j
解决方法
授予用户锁表权限即可。
网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。
mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。
导数据库报上面错,添加参数--single-transaction
# X( J$ ^; J& |2 J! [: ^[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction  >/root/zhongnan-nova.sql
1 W5 d) o* E% A2 Q# T" q8 V$ c# Wmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)/ I: m' E* j% `  `; q  Y( D; j
1 ~3 S2 r% N! t2 D( D
还是报错::
9 i7 l& R  f( S! l) T$ D登录到数据库中show
# h  J2 Q0 I' [  B  D3 wMariaDB [nova]> show create table `agent_builds` ;& x! L  V2 q7 ?  u- a# r$ u% O
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'
' z4 G! y# V( n% {0 C8 b% r8 I* N查看数据结构:3 a6 W4 l7 j  d4 B# h
MariaDB [nova]> desc agent_builds;
, U# {" f+ p" n. uERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'$ t* D7 D3 _+ x( I$ N

  R% H6 G' t& @( Y- |root@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql
: B- Q, U7 W+ lmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)( Y! Q# [- l( E2 P" t

: m5 v8 R9 p0 e; a+ Y+ |8 C8 |
# M# `6 G9 T* @# R( a2 q今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。
& g( m9 s6 T4 U   遇到该问题,解决方案如下:7 Y1 W0 s( ^7 l  \' D; b/ n3 G
   在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:9 N: O# Y2 o# i0 B" _
  mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp3 C. Y) Y, J: U; D0 M. c3 Z
5 e- H& o4 {+ C' w; G
   下面是对事务表使用LOCK TABLES的说明:
/ V  x) y4 ^' U* t      在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES
7 S) [+ ^4 F6 q$ W       对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。
% l( A8 P' X$ j8 ~, l& @      ROLLBACK不会释放MySQL的非事务表锁定。5 m0 W& \( ^) A) ?
       要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。( b" ]3 b3 o, k2 O; m& t$ e0 L
       使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。/ L3 M/ W1 Y3 ^; p- B7 F! |
如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。
, K' j: t) a. G; _4 CREAD LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。
' W2 k1 |4 X2 H0 ~       当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。7 X1 C+ k2 n, h, O
mysql> LOCK TABLE t WRITE, t AS t1 WRITE;
9 s  ~3 C6 d% X1 B
6 g) x; v2 g* x; A0 t8 ?mysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES  r8 j) m: U" j" r  k1 Q
' W$ `) ?7 N. b2 @- T0 z9 o
mysql> INSERT INTO t SELECT * FROM t AS t1;    如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。
( {) c* y; N  C' W& y6 d% D1 Pmysql> LOCK TABLE t READ;& w) G2 {5 ?7 l+ ^# ]* d1 `

! L1 F6 ~5 f& o' j+ Zmysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。
* u! {+ I3 n* D5 Wmysql> LOCK TABLE t AS myalias READ;
  i) P) f, H0 t, \0 k/ m2 Q9 f- K
mysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES
) T( q% |# h- J' _  m7 _( H
6 g0 q# d' ^1 o: |mysql> SELECT * FROM t AS myalias;  Y5 [, M4 j8 h# M+ M& }7 [8 \
WRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。7 L. w' d% F# A! R7 B9 \6 z* g0 U
LOCK TABLES按照如下方式执行:
" ]+ X8 ?: U! v& ?" v& _1.    按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。+ @/ @! ~+ E& Z* \: |
2.    如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。
4 y1 i0 j5 A: z4 z) ?% b2 p3.    一次锁定一个表,直到线程得到所有锁定为止。  y7 _. O2 q4 h* Z
该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:
% ^8 }6 c1 ^7 z8 N# b如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。6 e2 f) V- a% v* n6 W' T
您可以安全地使用KILL来结束一个正在等待表锁定的线程。
! A$ N- R" f1 }8 W- b& ^: M9 ?注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。! @  u! ~' p, }' u
通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:) T- z( B7 i( H. a
        如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。) Q0 H2 C% F% p1 e
有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。
, o. n1 T( Q# p" p& b7 @        如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:3 u! B  \0 [8 L& [* d. F2 [
              mysql> LOCK TABLES trans READ, customer WRITE;·                ' R1 y4 n( d5 A& j, A

& i, V* Q- C2 z! [) Kmysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·               
- e2 ?' l; c" f4 t7 |5 W3 Q+ Y
6 a6 y. C* Z* F3 Y9 D1 [. L& l$ Gmysql> UPDATE customer·                    
5 q1 W' x. A# |1 b2 Q& _->     SET total_value=sum_from_previous_statement·                  
- j" r; m7 Z9 Y: S  ->     WHERE customer_id=some_id;·                8 O& R/ Z. F/ |( W5 Q+ n
" N  ?/ G3 g3 M" t
mysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。2 P) k( _; o- w  y
通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。
- C  b! a, U( s" v( ^1 h- e0 P9 P通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。1 ^2 q) V" T8 [; H1 f
要了解更多有关锁定规则的说明
) J( y# m" R; g. O! j. l您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。
( b% h& R1 \& ^- \4 L3 k注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。
. y. R9 t  P- B2 F5 Q' F8 K7 E0 V# M5 z$ V, Z

! r' W! N1 w! ^2 }* Q- ^9 ^& C( `" U; y" N; K
在一个网站上看到一个解决方法:
$ U$ M/ Q; c" Z' P1.创建一个暂存鱼眼/坩埚服务器' w1 H  J1 w! F* X0 |" ?
2.连接到另一个MySQL数据库服务器
0 W7 G) r  Q, p, z3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件( z2 n) a: a/ w& r
4.重启Fisheye/Crucible生产服务器
; w  [. ]( q) s6 w* H6 d$ q
8 n0 }+ ?, w  S: Q# e. B

3 i" W" s4 z. G! P

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-1-10 16:28:05 | 显示全部楼层
1.创建一个暂存鱼眼/坩埚服务器
8 y1 C8 V4 p, u( N& M2.连接到另一个MySQL数据库服务器
% r1 w6 E: I3 [/ Q1 R3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件0 r1 [1 M6 Q2 a* L9 D
4.重启Fisheye/Crucible生产服务器
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 02:10 , Processed in 0.018293 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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