易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 1462|回复: 1
收起左侧

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

[复制链接]
发表于 2022-1-10 15:52:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x
执行导出数据库:
/ L, I2 }4 b1 q7 b* N; nmysqldump -u root -predh3 nova >/root/zhongnan-nova.sql % ?( Z  ]7 Q% w: s) H& t' P5 o
mysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES2 I" W* m! v: t& y/ ^, l0 Y# @2 U
报错了:
1 i# u& L1 A$ a0 _. V5 h0 PGot error: 1033:   
$ w# E0 f0 V. H& y  Xwhen using LOCK TABLES
, j0 V$ B+ I% k解决方法
授予用户锁表权限即可。
网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。
mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。
导数据库报上面错,添加参数--single-transaction ! i" A- i& Z; H: T+ j* b
[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction  >/root/zhongnan-nova.sql
9 j+ I; z- n0 g3 x6 Z4 nmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)' i( _. @" V; [; v
  m$ X! V+ H7 a# a+ G) k7 T& ?
还是报错::4 o, I) d+ ?! _
登录到数据库中show
' p+ J3 N7 k6 h$ j% M6 ~MariaDB [nova]> show create table `agent_builds` ;+ s2 b" ~1 k6 o( |9 q1 m
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'3 e6 P; L! [% Y+ r
查看数据结构:8 ?% [1 c: p' |* `0 \# \
MariaDB [nova]> desc agent_builds;" O- \" S8 Z5 g, {! @
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm': L& ?5 e. b: Y5 x
+ v# R* S' S+ B" w# C
root@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql 5 P( z7 w" W' R9 ~! i
mysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)% B4 n' k8 e7 f& |1 I5 I  O: ]
+ U) L  z$ s0 s; `7 y

  r% p) D7 ~# f1 n今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。0 V/ |. x6 |! B# ]% G# h$ }
   遇到该问题,解决方案如下:  Y1 ~5 U8 E7 D9 y
   在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:
0 Z2 K: t, H# ?  mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp2 E8 E! k' J: A
6 _- g4 l8 C* h# g, i1 [. A0 K
   下面是对事务表使用LOCK TABLES的说明:% S; L4 z: ?6 f+ s6 @% J
      在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES
4 I2 c3 W1 O; s# s1 K       对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。
. P7 l: u5 I+ k4 J8 Q      ROLLBACK不会释放MySQL的非事务表锁定。
/ h2 |/ d3 v7 X4 c: O% [5 J       要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。
, a; i) B  ?* D1 u2 X$ Y       使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。
9 B/ u9 |- y8 f. l1 I如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。
$ H) e' @% v- c* Q9 s7 VREAD LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。
& D* e6 M# Z! H! M! b       当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。
- x4 E9 ~6 G  O9 f' d3 Q, Gmysql> LOCK TABLE t WRITE, t AS t1 WRITE;
% |; u' L% T: ~" p# ^8 s/ M1 x4 |% C: q, e2 i2 F
mysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES
" ?$ W* Z9 ~/ G3 Q0 F
+ Y) ^; s  w8 imysql> INSERT INTO t SELECT * FROM t AS t1;    如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。
# e9 Y0 S' M. v7 h5 K0 i3 Smysql> LOCK TABLE t READ;
( c- D, I% M' Q$ o
3 g- ?' V# C, F" ^: i- U; Nmysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。8 b! d1 N% b1 L' T
mysql> LOCK TABLE t AS myalias READ;
* |# J6 r$ ]% N+ J. k$ U' c( H4 h. ^# h9 \: {- z
mysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES
5 S/ T6 |& w* J/ ^, u
, ^: w6 a, l" r- o7 _1 s' |+ Lmysql> SELECT * FROM t AS myalias;
1 L" E( m/ |1 q7 C1 n  N4 ^, D& K  NWRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。$ x  E6 I5 a2 G0 ~" A* ~! M1 T8 T" s
LOCK TABLES按照如下方式执行:: W+ i" D0 c- G( ?) B$ R: L9 C2 s
1.    按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。# {$ t! y- V  `
2.    如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。3 ^5 H  U, W  x4 M! T: t
3.    一次锁定一个表,直到线程得到所有锁定为止。7 f# ~8 K9 Y' P* E& }
该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:) S' R- i/ P* g) n$ Q4 N- Y5 Y
如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。
5 J) U# s* p. m& v您可以安全地使用KILL来结束一个正在等待表锁定的线程。
! A) e! l+ m) q注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。% G' y+ _6 J+ \9 c2 W6 O
通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:2 ~' M) x$ j( s- `2 J
        如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。- z  p) p8 O8 C9 S
有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。
: o% ^' x. d# i( ?7 t1 k        如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:: ^/ @' L5 a4 v
              mysql> LOCK TABLES trans READ, customer WRITE;·               
% }# u) p6 o- j1 Y2 ~9 W( K5 Y
* o9 b1 P' e5 K1 \! Ymysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·               
3 C) Q: n, O" J2 j  f& A/ E
- I/ ~0 w; I( k2 U$ o6 S9 Kmysql> UPDATE customer·                    $ [# U. S0 O0 O% X  b; V, ^8 z
->     SET total_value=sum_from_previous_statement·                    H8 a! a9 ~* q/ o3 J
  ->     WHERE customer_id=some_id;·               
9 E# ]1 i* l, m  `
6 [$ I# u! M( g5 _mysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。
0 j8 k& f7 J8 ~! H. c9 M通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。
7 W8 W" N( R* E1 E7 t& m) o3 u: }通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。% }- Q, V3 u; ^5 N" B
要了解更多有关锁定规则的说明
  g: Z) c. f0 j. h3 G. i您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。1 @$ }% t+ p2 k! \  t" o4 K
注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。8 p! ~% y0 |  `! T; J

* I) b/ l3 u$ A
. B# ~. G- j% m- o7 U
8 d2 T4 S. @; q8 H8 S* ]5 B" X+ y在一个网站上看到一个解决方法:1 Z& |- o: m; n: ~1 m% |: z) [- J) x
1.创建一个暂存鱼眼/坩埚服务器' G4 X/ b) [$ G+ z4 l0 U
2.连接到另一个MySQL数据库服务器, C& A5 ~! f5 X5 M2 U. A- Q5 S2 d
3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件: a  P/ D* C3 w1 r
4.重启Fisheye/Crucible生产服务器

' A0 H, d5 |8 e$ _& g, u' T
" K- H: _: G- ~' i9 v$ Q
3 a: [1 C2 u0 Z7 R
 楼主| 发表于 2022-1-10 16:28:05 | 显示全部楼层
1.创建一个暂存鱼眼/坩埚服务器( A& R2 [) z6 S) n( a& V$ e
2.连接到另一个MySQL数据库服务器
" H6 i- X6 |0 {2 X" m# _8 P8 b3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件
  i: O# V8 w- Y) M4.重启Fisheye/Crucible生产服务器
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-8 20:17 , Processed in 0.052861 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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