开发中遇到的l异常(mysql为主)

来源:互联网 发布:元数据丢失可以测试么 编辑:程序博客网 时间:2024/05/16 05:47

connection holder is null druid:

数据库连接异常   connection holder is null druid  ........优化执行修改解决在连接执行时间内执行完成

注意对多线程的支持:

引用第三方工具注意对多线程的支持,

 获取charset异常  java.util.ConcurrentModificationException

MD异常  java.io.IOException: Channel not open for writing - cannot extend file to required size

寻找多线程解决方案,或者将工具实例改为多个。

Packet for query is too large:

 (760377038 > 268435456)

/etc/my.cnf下配置,设置max_allowed_packet,每次提交数据的最大大小M

innodb_log_file_size=4096M

innodb_log_buffer_size = 8M

将缓存文件和缓存设置大一些,避免了相关异常。

 Incorrect string value:

'\xF3\xB2\xBF\xB7\xD6\xB6...' for column 'content' at row 1

从新浪微博抓到的数据在入库的时候抛出异常:

Incorrect string value: '\xF0\x90\x8D\x83\xF0\x90...' 

发现导致异常的字符不是繁体而是某种佛经文字.

 

Mysql入库汉字是乱码,当前编码utf-8

原来问题出在mysql上,mysql如果设置编码集为utf8那么它最多只能支持到3个字节的UTF-8编码,而4个字节的UTF-8字符还是存在的,这样一来如果你建表的时候用的utf8字符集出异常就理所当然了。

解决方法很简单,修改字段或者表的字符集为utf8mb4

比较蛋疼的是,字符集utf8mb4mysql 5.5.3之后才支持

在执行insert之前执行set names ‘utf8mb4’就可以了。  保存之前调用initConnect()

Lock wait timeout exceeded; try restarting transaction

说明:

1、锁等待超时。是当前事务在等待其它事务释放锁资源造成的。可以找出锁资源竞争的表和语句,优化你的SQL,创建索引等,如果还是不行,可以适当减少并发线程数。

2、你的事务在等待给某个表加锁时超时了,估计是表正被另的进程锁住一直没有释放。

可以用 SHOW INNODB STATUS/G; 看一下锁的情况。

3、在管理 节点的加:

TransactionDeadLockDetectionTimeOut=10000(设置10秒)默认是12001.2秒)

4

InnoDB会自动的检测死锁进行回滚,或者终止死锁的情况。

引用

InnoDB automatically detects transaction deadlocks and rolls back a transaction or transactions to break the deadlock. InnoDB tries to pick small transactions to roll back, where the size of a transaction is determined by the number of rows inserted, updated, or deleted.

 

如果参数innodb_table_locks=1并且autocommit=0时,InnoDB会留意表的死锁,和MySQL层面的行级锁。另外,InnoDB不会检测MySQLLock Tables命令和其他存储引擎死锁。

你应该设置innodb_lock_wait_timeout来解决这种情况。

innodb_lock_wait_timeoutInnodb放弃行级锁的超时时间。

问题描述和解决:

多台服务器引擎侧和平台:虽然是行级锁,但平台侧和引擎侧调用妨碍,导致死锁和事务回滚。(一段时间事务全部回滚了)

innodb_lock_wait_timeout=50  默认50

Got an error from unknown thread  ||  Incorrect key file for table '/tmp/#sql_15cc_14.MYI'; try to

mysqllocalhost.localdomain.err文件看到如下内容:

2016-05-25 15:21:05 2599 [ERROR] Got an error from unknown thread, /export/home/pb2/build/sb_0-11248666-1389714123.71/mysql-5.6.16/storage/myisam/mi_write.c:226

2016-05-25 15:48:01 2599 [ERROR] /usr/local/mysql/bin/mysqld: Incorrect key file for table '/tmp/#sql_a27_1.MYI'; try to repair it

2016-05-25 15:48:01 2599 [ERROR] Got an error from unknown thread, /export/home/pb2/build/sb_0-11248666-1389714123.71/mysql-5.6.16/storage/myisam/mi_write.c:226

2016-05-25 15:48:01 2599 [ERROR] /usr/local/mysql/bin/mysqld: Incorrect key file for table '/tmp/#sql_a27_2.MYI'; try to repair it

2016-05-25 15:48:01 2599 [ERROR] Got an error from unknown thread, /export/home/pb2/build/sb_0-11248666-1389714123.71/mysql-5.6.16/storage/myisam/mi_write.c:226

java代码报如下错误:

 Incorrect key file for table '/tmp/#sql_15cc_14.MYI'; try to repair it

 

查询后得知可能是tmp空间不足引起。

使用语句查看进程使用情况。

SELECT * FROM information_schema.`PROCESSLIST` WHERE INFO IS NOT NULL ;

如果有占用较大的文件或者进程直接删除之应该可以解决

 

查看当前使用

linux临时空间:df -h   发现tmpfs 16G满的(查看 cat /etc/fstab文件也是一样)

发现一个表太大完全无法加载。

MYSQLHIBERNATE结果为NUll/不符合预期,in的问题

String sql = "select GROUP_CONCAT(id SEPARATOR ',') from sys_user where user_role_id in (?) or (user_role_id = ? and user_role = 0)";

String idStr = (String)this.createSQLQuery(sql,roleStr,roleId).list().get(0);

String idStr = (String)this.createSQLQuery(sql).uniqueResult();

获得idStr有时候为null,有时候一直,传入条件一样。

据说是in的问题,在有in的时候直接将sql拼装好,不要传参。

 

误删除.ibd .frm文件 无法创建新表

在新数据库中创建表,然后将.frm表结构文件复制过去,重启mysql,drop表。

 

 

This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled

 (you *might* want to use the less safe log_bin_trust_function_creators variable)

 

原来是因为在主从复制的两台MySQL服务器中开启了二进制日志选项log-bin,slave会从master复制数据,而一些操作,

比如function所得的结果在masterslave上可能不同,所以存在潜在的安全隐患。因此,在默认情况下会阻止function的创建。

这是我们开启了bin-log, 我们就必须指定我们的函数是否是
1 DETERMINISTIC 不确定的
2 NO SQL 没有SQl语句,当然也不会修改数据
3 READS SQL DATA 只是读取数据,当然也不会修改数据
4 MODIFIES SQL DATA 要修改数据
5 CONTAINS SQL 包含了SQL语句

其中在function里面,只有DETERMINISTIC, NO SQLREADS SQL DATA被支持。如果我们开启了bin-log,我们就必须为我们的function指定一个参数。


MySQL中创建函数时出现这种错误的解决方法:
set global log_bin_trust_function_creators=TRUE;

 Mysql ibdata 丢失或损坏如何通过frm&ibd 恢复数据

MySQL存储在磁盘中,各种天灾人祸都会导致数据丢失。大公司的时候我们常常需要做好数据冷热备,对于小公司来说要做好所有数据备份需要支出大量的成本,很多公司也是不现实的。万一还没有做好备份,数据被误删除了,或者ibdata损坏了怎么办呢?别担心,只要有部分的frm、ibd存在就可以恢复部分数据。

注意:
一、这个是对innodb的数据恢复。myisam不需要这么麻烦,只要数据文件存在直接复制过去就可以。
二、大家的mysql数据库必须是按表存放数据的,默认不是,但是大家生产肯定是按分表设置的吧,如果不是,不好意思,这个方法不能恢复你的数据。my.ini的设置为 innodb_file_per_table = 1。

参考 http://blog.chinaunix.NET/uid-24111901-id-2627876.html

1、找回表结构,如果表结构没有丢失直接到下一步

    a、先创建一个数据库,这个数据库必须是没有表和任何操作的。
    b、创建一个表结构,和要恢复的表名是一样的。表里的字段无所谓。一定要是innodb引擎的。CREATE TABLE `weibo_qq0`( `weiboid` bigint(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    c、关闭mysql, service mysqld stop;
    d、用需要恢复的frm文件覆盖刚新建的frm文件;
    e、修改my.ini 里 innodb_force_recovery=1 , 如果不成修改为 2,3,4,5,6。
    f、 启动mysql,service mysqld start;show create table weibo_qq0 就能li到表结构信息了。

2、找回数据。记得上面把 innodb_force_recovery改掉了,需要注释掉,不然恢复模式不好操作。 这里有个关键的问题,就是innodb里的任何数据操作都是一个日志的记录点。也就是如果我们需要数据恢复,必须把之前的表的数据的日志记录点添加到一致。

    a、建立一个数据库,根据上面导出的创建表的sql执行创建表。
    b、找到记录点。先要把当前数据库的表空间废弃掉,使当前ibd的数据文件和frm分离。 ALTER TABLE weibo_qq0 DISCARD TABLESPACE;
    c、把之前要恢复的 .ibd文件复制到新的表结构文件夹下。 使当前的ibd 和frm发生关系。ALTER TABLE weibo_qq0 IMPORT TABLESPACE; 结果不出意外肯定会报错。就和我们开展数据开始说的那样,数据记录点不一致。我们看看之前ibd记录的点在什么位置。开始执行 import tablespace,报错 ERROR 1030 (HY000): Got error -1 from storage engine。找到mysql的错误日志,InnoDB: Error: tablespace id in file ‘.\test\weibo_qq0.ibd’ is 112, but in the InnoDB InnoDB: data dictionary it is 1. 因为 weibo_qq0 之前的记录点在112,当前的表只创建一次,所以记录点是1.
    d、那怎么从1记录到112。for ($1=1; $i<=111; $1++) {CREATE TABLE t# (id int) ENGINE=InnoDB;} 也许很奇怪,为什么是循环111,不是112。因为在a执行创建表结构的时候已经记录增加了一次。 e、修改表结构 alter table weibo_qq0 discard tablespace;使当前的表结构和ibd脱离关系。复制.ibd到当前的目录结构。 f、使原来数据的ibd和当前frm建立关系。 ALTER TABLE product IMPORT TABLESPACE; 这个时候没有错误,说明已经建立好了。但是查询数据还是查不出来。 g、相比这里大家已经知道为什么了,这个模式也不是说改了数据库就可以在生产环境使用。更改 innodb_force_recovery=1 , 如果不成修改为 2,3,4,5,6。直到可以 查询出数据为止,然后dump出来。数据就备份出来了。 h、把所有数据导出后,在新的数据库导入。所有数据就生成了。

扩展问题,很多时候我们是分表表结构怎么批量操作,提高速度呢。用循环!循环把表的空间废弃掉。
for i in `seq 0 111`; do mysql -uroot -P33061 -h127.0.0.1 -Dtestdd -e “CREATE TABLE inv_crawl_weibo_qq$i (id bigint(20) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id)) ENGINE=innodb “; done
ALTER TABLE inv_crawl_weibo_qq0 DISCARD TABLESPACE;
从备份数据把ibd复制cp到dd数据库下,注意复制过来的文件权限。
循环导入表空间。
ALTER TABLE inv_crawl_weibo_qq0 IMPORT TABLESPACE;
没有报错就导入成功了


建议不用实体初始化表

通过实体初始化表  hql 新建级联表时  将    @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="host_scan_script_id")  放在字段前 不要放在get方法前,不然新建的级联表有问题。


QuerySyntaxException

有同事将 @Table应该写的表名放在了@Entity中【不仔细瞅真的注意不到啊】

QuerySyntaxException: HostScanScript is not mapped 将@Table该写的表名 写到了@Entity中  查询不报错,select count(*) 时报错【这个原理有哥们儿可以研究下,表名就是把大写变成下划线这种格式】

 

 

 

0 0