将设为首页浏览此站
开启辅助访问 天气与日历 收藏本站联系我们切换到窄版

易陆发现论坛

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

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

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

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

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

x
执行导出数据库:/ z7 }; k1 H$ w! g: a
mysqldump -u root -predh3 nova >/root/zhongnan-nova.sql 4 z, \7 r4 N' B3 h
mysqldump: Got error: 1033: "Incorrect information in file: './nova/agent_builds.frm'" when using LOCK TABLES; i0 ?% Z7 M% I6 J. a  D: B6 ^
报错了:
2 y# S3 p7 N; i- r5 xGot error: 1033:    9 _* q( R% o; A6 g, ^) z
when using LOCK TABLES* o( |7 W( S6 p
解决方法
授予用户锁表权限即可。
网上有人说使用 –skip-lock-tables,这个会影响数据的一致性(可能比丢数据还要遭糕),故不推荐使用这个方法。 –single-transaction 用于 Innodb 引擎的数据库 dump 时,可以不锁表。
mysql 锁表原理深入下去还有很多细节可以学习,可以参考 Ref 相关资料。
导数据库报上面错,添加参数--single-transaction
) m- r8 r! ^2 z3 v  Z/ i/ Z[root@compute03 ~]# mysqldump -u root -predh3 nova --single-transaction  >/root/zhongnan-nova.sql
/ E8 g5 I: L" N2 I) w6 Wmysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)
. b! m; o; [- s% I' q4 d: O6 u  X+ d  m0 J$ B$ F, a
还是报错::3 i# n' v1 ~1 r+ T
登录到数据库中show
' Z% O5 d. C! z/ W4 ?0 DMariaDB [nova]> show create table `agent_builds` ;; l+ l+ I2 E! A0 q1 N$ J
ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'
$ J; J- A5 @' l6 A. [% N2 N& k8 K查看数据结构:
, n0 }+ C  x& W) l. I1 R+ k2 R4 mMariaDB [nova]> desc agent_builds;
$ E# ~. h5 b# Y9 k- O" O1 E7 [ERROR 1033 (HY000): Incorrect information in file: './nova/agent_builds.frm'. t* d1 k8 @# K3 s
3 r1 w" y  ~) d; O- @6 A+ s* V
root@compute03 ~]# mysqldump -u root -predhat123 nova --single-transaction --skip-lock-tables >/root/zhongnan-nova.sql % C+ x+ B9 N/ B: r% R4 E. A
mysqldump: Couldn't execute 'show create table `agent_builds`': Incorrect information in file: './nova/agent_builds.frm' (1033)
: H$ A% x& ?4 M/ U" O' a6 w; X6 K$ X) O+ E; E& P
' I' |3 [1 z/ Z, }$ d, S
今天在备份一位客户的mysql数据库的时候,使用mysqldump命令备份,出现when using LOCK TABLES的提示。如果对mysql中的用户的权限进行过详细设置的话,会知道用户可以被分配LOCK TABLES和UNLOCK TABLES两个权限,使该用户在对该用户的表进行读写锁设定。3 a- E$ W$ w4 K) J+ J3 E
   遇到该问题,解决方案如下:$ p7 _  u% o! T5 h" g
   在执行备份的时候,将命令中添加 --skip-lock-tables,即命令如下:
, d& U8 F3 L7 k+ H  mysqldump -u 用户名 -p 用户密码 --skip-lock-tables -R database > /root/database_1120.dmp
, r$ n9 f( W0 k6 {
; Y: n2 X3 \  B& o: M3 k" }   下面是对事务表使用LOCK TABLES的说明:
4 F6 [; [# A/ [9 C, q! W      在尝试锁定表之前,LOCK TABLES不是事务安全型的,会隐含地提交所有活性事务。同时,开始一项事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES
, d% r8 Y- N6 r3 F       对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0并且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其自己的表锁定,MySQL取其自己的表锁定。InnoDB在下一个提交时释放其表锁定,但是,对于MySQL,要释放表锁定,您必须调用UNLOCK TABLES。您不应该让AUTOCOMMIT=1,因为那样的话,InnoDB会在调用LOCK TABLES之后立刻释放表锁定,并且很容易形成死锁定。注意,如果AUTOCOMMIT=1,我们根本不能获取InnoDB表锁定,这样就可以帮助旧的应用软件避免不必要的死锁定。0 ?; C7 U; E; W9 q/ V# @
      ROLLBACK不会释放MySQL的非事务表锁定。
$ f4 G0 V+ J+ Y8 Y" r3 ?       要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。$ ~) _1 N- J% Q0 S
       使用LOCK TABLES的主要原因是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。0 Y/ k- l) Q2 J$ U: ]7 i. r
如果一个线程获得对一个表地READ锁定,该线程(和所有其它线程)只能从该表中读取。如果一个线程获得对一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。其它的线程被阻止,直到锁定被释放时为止。
6 ?$ e9 A  R) k; S. u- b6 YREAD LOCAL和READ之间的区别是,READ LOCAL允许在锁定被保持时,执行非冲突性INSERT语句(同时插入)。但是,如果您正打算在MySQL外面操作数据库文件,同时您保持锁定,则不能使用READ LOCAL。对于InnoDB表,READ LOCAL与READ相同。) F5 i0 L8 u* A- Q; i
       当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。虽然使用LOCK TABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,在此情况下,您必须分别获得对每个别名的锁定。
0 }5 A: w7 f4 J+ v6 y( ?: amysql> LOCK TABLE t WRITE, t AS t1 WRITE;$ V3 u3 Q- C9 P4 L

  b3 W3 z* J4 o+ `1 L8 L0 ?5 ^mysql> INSERT INTO t SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES* x4 _+ J% |, h$ S) O( m7 S
, O. I$ k- r9 Z& O/ {: g5 R
mysql> INSERT INTO t SELECT * FROM t AS t1;    如果您的查询使用一个别名引用一个表,那么您必须使用同样的别名锁定该表。如果没有指定别名,则不会锁定该表。- N: F1 `: T: q0 Z
mysql> LOCK TABLE t READ;
( E" c* N) A6 u5 n: {2 v
# z! r5 o5 G9 X3 zmysql> SELECT * FROM t AS myalias;ERROR 1100: Table 'myalias' was not locked with LOCK TABLES相反的,如果您使用一个别名锁定一个表,您必须使用该别名在您的查询中引用该表。
. r8 X0 q; o% U9 Q# Dmysql> LOCK TABLE t AS myalias READ;
- N. P& F4 \3 d  S) c0 C: d5 T
mysql> SELECT * FROM t;ERROR 1100: Table 't' was not locked with LOCK TABLES5 T# E4 r. J) ^9 {. G3 W' G

2 q6 ^9 s) @9 K4 D1 tmysql> SELECT * FROM t AS myalias;
& w  n. p& [! ]: S- BWRITE锁定通常比READ锁定拥有更高的优先权,以确保更新被尽快地处理。这意味着,如果一个线程获得了一个READ锁定,则另一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程获得锁定并释放锁定。您可以使用LOW_PRIORITY WRITE锁定来允许其它线程在该线程正在等待WRITE锁定时获得READ锁定。只有当您确定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使用LOW_PRIORITY WRITE锁定。0 p0 y0 l+ q. J8 R3 I3 j  f
LOCK TABLES按照如下方式执行:# p+ {5 z$ `2 q6 _" W
1.    按照内部定义的顺序,对所有要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。( V$ R1 M" M. _5 E* c& V) m# N
2.    如果使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定之前。
5 r! M* Y, p$ Z- _+ j" b3.    一次锁定一个表,直到线程得到所有锁定为止。! D; k+ _/ C: A- V
该规则确保表锁定不会出现死锁定。但是,对于该规则,您需要注意其它的事情:
% Q# ?, F( z2 {) I# Y, ~, G如果您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有申请READ锁定的线程时为止。当线程已经获得WRITE锁定,并正在等待得到锁定表清单中的用于下一个表的锁定时,所有其它线程会等待WRITE锁定被释放。如果这成为对于应用程序的严重的问题,则您应该考虑把部分表转化为事务安全型表。
% _# B- L/ M1 k, Z( d8 }您可以安全地使用KILL来结束一个正在等待表锁定的线程。: q6 g" y/ t- i' M. J
注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,因为,在这种情况下,INSERT由另一个线程执行。
* A; s' @3 }+ h5 P0 r通常,您不需要锁定表,因为所有的单个UPDATE语句都是原子性的;没有其它的线程可以干扰任何其它当前正在执行的SQL语句。但是,在几种情况下,锁定表会有好处:- D# I0 J  N& y3 I" U
        如果您正在对一组MyISAM表运行许多操作,锁定您正在使用的表,可以快很多。锁定MyISAM表可以加快插入、更新或删除的速度。不利方面是,没有线程可以更新一个用READ锁定的表(包括保持锁定的表),也没有线程可以访问用WRITE锁定的表(除了保持锁定的表以外)。
" S% ?  E! L) W, J6 Q' C有些MyISAM操作在LOCK TABLES之下更快的原因是,MySQL不会清空用于已锁定表的关键缓存,直到UNLOCK TABLE被调用为止。通常,关键缓存在每个SQL语句之后被清空。+ T) s) R) l9 Z
        如果您正在使用MySQL中的一个不支持事务的存储引擎,则如果您想要确定在SELECT和UPDATE之间没有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行:
. D4 B9 U& Q: Z. i: @( u/ a4 B              mysql> LOCK TABLES trans READ, customer WRITE;·               
5 ^0 b$ @) }! @9 s; U* b) Y
; t4 A, r, W2 O9 }4 `mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id;·               
0 }' }  W: _, g% l3 C, j* a# ?$ F% b/ u
mysql> UPDATE customer·                    
6 u8 A- d# R4 [" a->     SET total_value=sum_from_previous_statement·                  
( H- D* L9 c7 s! |  ->     WHERE customer_id=some_id;·               
+ C+ Z" ~  Z9 K: @/ C3 |9 i
; \3 a! i2 ]- p/ bmysql> UNLOCK TABLES;如果没有LOCK TABLES,有可能另一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。: h- J# f) ?% U# ~: \7 b- ]7 k) `
通过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您可以在许多情况下避免使用LOCK TABLES。3 O0 F) m/ |3 w2 \) Q7 a- P; O. I  L
通过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也可以在有些情况下避免锁定表。这些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速度。
9 M2 `( f6 Z2 ?) X4 `* H; H2 \! ?要了解更多有关锁定规则的说明
* q( O6 u+ a- Q- l! Q) {4 C5 f您可以使用FLUSH TABLES WITH READ LOCK语句锁定位于所有带有读取锁定的数据库中的所有表。如果您有一个可以及时拍摄快照的文件系统,比如Veritas,这是获得备份的一个非常方便的方式。
& M) p8 S  q# P) o注释:如果您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。
; q- K; @5 K; x+ z) l- L( v1 S
' m3 c, G  U2 M5 c! Q
" _/ s% r9 p. F4 J0 b! a% M9 N
/ O$ s! ^- E+ W  U# g在一个网站上看到一个解决方法:
* m; @; v& c  `/ t1.创建一个暂存鱼眼/坩埚服务器4 [, w% q: X. p+ f, J  _: F
2.连接到另一个MySQL数据库服务器+ U9 W6 F2 Z$ E' [, C8 s. c) _
3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件6 a  {/ w( w: x$ g
4.重启Fisheye/Crucible生产服务器

  _+ z" v/ i" p$ C7 Q+ _) y) o( ?6 W0 N. R: y3 e( e' b
% Y* H* p$ Q# y; Q; v7 M
 楼主| 发表于 2022-1-10 16:28:05 | 显示全部楼层
1.创建一个暂存鱼眼/坩埚服务器2 `. o/ d2 E/ V5 y  v
2.连接到另一个MySQL数据库服务器/ P+ }8 t0 W1 [4 M
3.从新数据库中,复制相同的 .frm 文件以替换生产服务器中有问题的 .frm 文件
% r& D3 T$ E0 q& w8 r4.重启Fisheye/Crucible生产服务器
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

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

如有购买积分卡请联系497906712

QQ|返回首页|Archiver|手机版|小黑屋|易陆发现 点击这里给我发消息

GMT+8, 2022-1-22 13:09 , Processed in 0.044653 second(s), 21 queries .

Powered by LR.LINUX.cloud bbs168x X3.2 Licensed

© 2012-2022 Comsenz Inc.

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