易陆发现互联网技术论坛

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

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

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

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

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

x
执行导出数据库:7 z" z$ n. q3 [$ r7 h
mysqldump -u root -predh3 nova >/root/zhongnan-nova.sql 9 U9 _- H: G. T: W7 ~4 H
mysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES
/ Y( W1 P1 Y( h& W8 @) `( ?报错了:# D9 d2 D+ [" L$ W8 g$ K: T
Got error: 1033:    ! p- {  ~) Q) k
when using LOCK TABLES
3 K/ ^4 I. F( b2 k# S0 s0 v# p解决方法
授予用户锁表权限即可。
网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。
mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。
导数据库报上面错,添加参数--single-transaction - g4 X$ M% I' ^( r8 X/ i9 g5 D
[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction  >/root/zhongnan-nova.sql 2 N% p( w0 p2 T6 ]$ b& R3 f
mysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)& i7 x0 \- }% n4 q# e( e8 Y
9 i/ `' b. _. r$ Q! j8 j
还是报错::
3 B( D# p+ d# n4 x# h/ v4 O9 _登录到数据库中show + s0 C  @( c- y3 @) |
MariaDB [nova]> show create table `agent_builds` ;9 ?- n9 p% b  x7 R& [: f9 W8 A
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'
& L! x0 k8 C, V8 F# f% u- I" S查看数据结构:0 Z% |, I/ G' o% c
MariaDB [nova]> desc agent_builds;; u' n' f+ _% t4 m0 O: c
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'
' Y6 k2 Z; t: T
7 G# J  c, @$ Q! x; B8 Troot@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql
5 j# d3 r& O) w+ v" Z* o4 s% Lmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)
$ A/ Z$ _! ^' d
) S1 X# V  J( `+ p) |6 m) s# Z1 t
5 e! o1 Z7 b2 v) t: f今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。9 q0 Z- c! j$ m/ d/ W
   遇到该问题,解决方案如下:
5 b  v  j  m, L" L, f/ ~& {6 d   在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:
% E2 R' [5 |3 x8 J: n  mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp2 F& R. c, ]$ ?

! E2 J1 x; x. w   下面是对事务表使用LOCK TABLES的说明:/ m8 d; {$ Y5 u/ u* y2 I! U8 e2 Z
      在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES; X7 H9 E8 K/ ~, e/ R2 W4 q
       对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。
% P: y- a" y7 v! P% ?      ROLLBACK不会释放MySQL的非事务表锁定。
( m: ^1 g& |) s1 c% {       要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。5 a- H: P6 b$ R, t  e3 z0 O
       使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。
+ b2 z: y! x5 l$ @4 e* Z1 @" I/ o4 H& N如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。  H6 i9 C; O/ l* g  b$ ^2 f
READ LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。
1 B# Q7 O4 L- }/ V' W+ s' T       当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。1 z2 Z' t% _4 I, H1 o5 \
mysql> LOCK TABLE t WRITE, t AS t1 WRITE;- P* z, k3 X, V4 Y; b
# A% Y# g8 z/ b- u
mysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES
; J& A% Q& y7 I: N5 A/ o
% [6 X+ h9 }: }7 lmysql> INSERT INTO t SELECT * FROM t AS t1;    如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。- j* L: p) N4 r8 }9 o+ _
mysql> LOCK TABLE t READ;2 R+ p" C+ e" ]% d  J4 B+ a

0 A: o7 b' J) g: O" \mysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。
3 j4 `2 C' s, ^( E* n) W: F0 Rmysql> LOCK TABLE t AS myalias READ;
4 F" {& |7 M* W( L3 p% S1 L7 U, x* j- @1 N2 P" V
mysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES" V" g& u4 X1 h/ Z8 K2 h3 i+ m
' U( t4 A( d1 I0 D1 d
mysql> SELECT * FROM t AS myalias;7 e! f" s" Q2 |
WRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。8 K% _& b9 N4 k; c3 m: A
LOCK TABLES按照如下方式执行:' U7 n1 k" K) _9 d
1.    按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。& I4 R3 E7 c/ |5 l% p2 {
2.    如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。
3 `+ ]- w6 v, L% T7 `3.    一次锁定一个表,直到线程得到所有锁定为止。
' `& _" R8 \2 A" E; T4 I$ l该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:5 |; V) y& j/ Z# g' g- o: {2 _
如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。+ e; t: m' {0 y0 C8 @' d. n
您可以安全地使用KILL来结束一个正在等待表锁定的线程。! s. h, V3 V+ \: l- {, F+ E
注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。! r5 t6 f5 a7 a' u- J, s
通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:
( ^8 f  y& k' ~# L/ g        如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。
: d7 J: U- [' |0 L! \: e: C有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。
% c) t7 V: h$ m  [! b3 a        如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:
6 r4 t% \5 \2 d* y8 y              mysql> LOCK TABLES trans READ, customer WRITE;·                # e- o$ O( L) l( A

  ^+ D5 |4 S+ l& s2 H7 zmysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·               
" M' `" q, @7 S9 F; ?. N- c9 U  l4 g0 c, Q
mysql> UPDATE customer·                      ^3 d: h5 A$ s5 d# [! A9 M# R- b
->     SET total_value=sum_from_previous_statement·                  % `- I2 y7 J. T+ W% b& z% z" P: q
  ->     WHERE customer_id=some_id;·                4 w' V: p4 S; I# r. [5 d
0 R) J5 r1 ^8 A' I
mysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。
9 c6 I2 b0 F  p0 E$ B4 X1 l通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。
) e/ t5 n3 X4 L. ~通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。( ^5 J; M# j" p2 B7 c
要了解更多有关锁定规则的说明
. X7 ^( P/ T' W5 [+ A8 p# T/ ~您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。# |/ u% s1 V. r! h
注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。+ V. B% p5 i1 f1 L# j- d

6 K( @+ k0 c+ f% V
; K! a3 _/ u8 o$ o; E- l# i( k) F) f: p: w, A3 m8 }& |
在一个网站上看到一个解决方法:
8 ?* ]/ x: g  b7 x& ]. c1.创建一个暂存鱼眼/坩埚服务器4 v8 _3 _9 s: d8 k$ S- x% R8 @
2.连接到另一个MySQL数据库服务器* o+ \) W7 n6 m2 M3 E/ ~0 w3 ]/ z, g
3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件/ S; j) }5 F% G% z
4.重启Fisheye/Crucible生产服务器

, d* S( b9 C# W2 e6 n. @. _
: n6 \( W7 d  G7 O4 H5 r4 J  U+ o9 }& w9 N" W; F
 楼主| 发表于 2022-1-10 16:28:05 | 显示全部楼层
1.创建一个暂存鱼眼/坩埚服务器
2 A4 O/ x- N# P  S0 `3 v9 Q2.连接到另一个MySQL数据库服务器
% t4 M! a! z' L3 `, a3 t8 N6 v3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件; u% s, O# b0 x# S2 r9 O
4.重启Fisheye/Crucible生产服务器
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

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

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

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 点击这里给我发消息

GMT+8, 2026-4-10 16:24 , Processed in 0.040505 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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