[size=small]突然断网,检查后通知我们UPS断电,db所在主机重启
1、连上后,发现pg主从不同步,主不向从传日志,从报错:
FATAL: could not connect to the primary server: could not connect to server:
发现从先启动成功,而主是后启动的,因此我们将从再次重启
service postgresql restart
开始正常传日志
2、过了一会,研发反应部分表的使用出现问题,主再次不传输日志,且无sender进程。
查看主库日志,发现报错:
ERROR: invalid page header in block 27073 of relation base/21078/
查看从库日志,发现类似报错
ERROR:insert_t_black:invalid page head in block 27073 of relation base/21078/
21078是tm_samples库的id号
通过查询:
select * from pg_class where relfilenode='';—t_black
应该是停电的时候,正好在进行数据的写入等操作,造成了数据损坏。
此时,我们进行了如下操作:
set zero_damaged_pages = on; --当这个参数为on的时候,会忽略所有数据有损坏的页面
vacuum full t_black;
tm_samples=# select count(*) from t_black;
WARNING: invalid page header in block 27069 of relation base/21078/; zeroing out page
WARNING: invalid page header in block 27070 of relation base/21078/; zeroing out page
WARNING: invalid page header in block 27071 of relation base/21078/; zeroing out page
WARNING: invalid page header in block 27072 of relation base/21078/; zeroing out page
WARNING: invalid page header in block 27073 of relation base/21078/; zeroing out page
count
---------
(1 row)
reindex table t_black;
再次select count(*) from t_black; --正常
再重启pg主从的服务,发现主从开始同步,后台没有再报刚刚那个错误
3、研发测试验证,发现插入部分hash值的时候,依然会刚刚那个错误
insert into t_black (sample_hash, sample_crc32, sample_sha1, virusname, avl_m, software_english,file_size, conditions_type,
sample_type, description,record_time, getname_time, developers, last_record_time, last_changename_time, source_id, ss_id, cps,level,keyhash,
sensitive_strings, behavior_info, relation_info,version,ratio,"AVL_Embed", "AVL_Adware", program_name, versionname, record_time_int ) SELECT sample_hash, sample_crc32, sample_sha1, virusname, avl_m, software_english,file_size, conditions_type,
sample_type, description,record_time, getname_time, developers, last_record_time, last_changename_time, source_id, ss_id, cps,level,keyhash,
sensitive_strings, behavior_info, relation_info,version,ratio,"AVL_Embed", "AVL_Adware", program_name, versionname, record_time_int
FROM t_white where sample_hash ='1E0CB07CDC71B2F994F5D3EB51050E3A';
程序报错:DatabaseError: invalid page header in block 27073 of relation base/21078/
只插入部分字段就没问题,但完整插入就不行。
这时,我们想到可能是文件系统损坏了,当有数据往刚刚那个坏块里面写的时候,就会触发报错。
同时,我们查到一共有4张表出现了坏块,分别是:
t_black
t_white
t_batch_sample
t_derivative
我们决定先对所有的表做一次vacuum,然后进行磁盘的检查------后面的操作都是娟姐做的,待她回来后补充,但她反应检查后依然不行,最后的方法是磁盘格式化,然后用从库的备份进行了覆盖恢复。
网页上有一些介绍的方法:
1)根据错误提示 ERROR: invalid page header in block 1 of relation base/34780/34781 我们可以找到相应的文件, 文件的路径为: 数据目录/base/34780/34781,只要用工具手动把上面提示的坏块清除即可。
在Linux下面可以用dd工具把相应的页面清除:
$dd if=/dev/zero of=/home/postgres/data/base/34780/42995 bs=8192 seek=1 count=1 conv=notrunc
2)数据库暂时恢复使用了,但这是临时的,如果是磁盘文件系统故障,不久还是会重现这个问题,临了再修复了一下
1.reboot进入单用户模式
2.umount出现数据库异常的磁盘
3.fsck -v -t -p /dev/sda1
4.reboot
因为把有坏块的主库留了个备份,想用这个备份做一些实验:
a.尝试找到更为直接修复的方法
b.换到其他硬盘好的地方去,看它到底是db本身的文件坏了,还是啥原因。
======================实验=======================
将/data和pg_xlog压缩,传到已经安装好pg的12.250上面。替换到原来的data目录,目录保留
# mkfs -t 文件系统 存储设备
注:
这里的文件系统是要指定的,比如 ext3 ;reiserfs ;ext2 ;fat32 ;msdos 等... ...
设备比如是一个硬盘的分区,软盘,光驱等.. ... 在格式化分区之前,您得懂得如何查看硬盘分区情况,并有针对性的格式化;
比如用 fdisk -l 来查看;
您也可以把分区格式化成其它的文件系统;比如我们把 /dev/sda6格式化为ext3 、ext2、reiserfs、fat32、msdos 文件系统,命令格式如下;
# mkfs -t ext3 /dev/sda6
# mkfs -t ext2 /dev/sda6
# mkfs -t reiserfs /dev/sda6
# mkfs -t fat32 /dev/sda6
# mkfs -t msdos /dev/sda6
2、添加分区的自动挂载
# cat /etc/fstab
UUID=f3b4f67a-7e8a-477f-8dca-a1d683aa8a57 / ext4 defaults 1 1
UUID=9345bbc6-c984-4e42-9149-b6b753 swap swap defaults 0 0
UUID=e514fd36-4424-4984-952c-f47c2 /home/pgsql ext4 defaults,noatime,nodiratime 0 0
UUID=2bba011f-7bb2-43cd-ba83-6dcf0b459a33 /opt/db_backup ext4 defaults,noatime,nodiratime 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
UUID在哪里看呢?
ls -l /dev/disk/by-uuid #查看sdc1对应的uuid值
使用df -T也可以查看到。
# df -T -h
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 104G 37G 62G 38% /
tmpfs tmpfs 16G 0 16G 0% /dev/shm
/dev/sdc1 ext4 917G 529G 342G 61% /opt/db_backup
/dev/sdb ext4 939G 147G 745G 17% /home/pgsql
cat /etc/fstab
df -T -h
mount
3、有多余的表空间,且没有该表空间的目录依然可以正常启动数据库,如何将该表空间进行删除?
could not open tablespace directory "pg_tblspc//PG_9.1_": No such file or directory 经查看就是表空间tm_data
postgres=# db
List of tablespaces
Name | Owner | Location
------------+----------+------------------
pg_default | postgres |
pg_global | postgres |
tm_data | postgres | /home/pgsql_data
(3 rows)
postgres=# drop tablespace tm_data;
ERROR: tablespace "tm_data" is not empty --非空的表空间不能直接删除。
select * from pg_tables where tablespace='tm_data';--查到有4张表在这个表空间下
"public";"t_mobile_virus_url_event";"postgres";"tm_data";f;f;f
"public";"t_mobile_virus_url_event";"postgres";"tm_data";f;f;f
"public";"t_mobile_virus_url_event";"postgres";"tm_data";t;t;f
"public";"t_mobile_virus_url_event";"postgres";"tm_data";t;f;f
先删除表,再删除表空间即可。
4、如何查看数据库的ID和表的ID?
select relfilenode from pg_class where relname='t_black'; --查看表的id
select datid,datname from pg_stat_activity where datname='tm_samples'; --查看库的id 暂时没找到更直接的办法
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/luakf/33477.html