Arxiv

Posts Tagged ‘binary log’

Making logical backup-binary log,mysqldump (part 2)

Yazının 1ci hissəsi
Bəli 2ci yazıda mysqldump-la full logical backup alacıq, restore edəcik.
Və ən sonda da binary log ilə çox sadə point-in-time recovery edəcik.
Ilk öncə nümunə schema və cədvəlimizi yaradaq:

mysql> create schema backup_test character set=utf8;
Query OK, 1 row affected (0.12 sec)

mysql> use backup_test;
Database changed
mysql> create table test_table(
    -> id int not null auto_increment,
    -> name varchar(15),
    -> surname varchar(20),
    -> primary key(id)
    -> );
Query OK, 0 rows affected (0.20 sec

3 İnsert-imizi edək:

mysql> insert into test_table(name,surname) values('Shahriyar','Rzayev'),('Khatai','Rzayev'),('Elvin','Binyatov');
Query OK, 3 rows affected (0.18 sec)
Records: 3  Duplicates: 0  Warnings: 0

Cədvəlimizin halı:

mysql> select * from test_table;
+----+-----------+----------+
| id | name      | surname  |
+----+-----------+----------+
|  1 | Shahriyar | Rzayev   |
|  2 | Khatai    | Rzayev   |
|  3 | Elvin     | Binyatov |
+----+-----------+----------+
3 rows in set (0.00 sec)

Və deyək ki cədvəlimizin bu halında biz full backup etmək qərarına gəldik…(yalnızca bu cədvəl yox bütün cədvəlləri)
Full logical backup mysqldump vasitəsilə yerinə yetirilir…Amma ilk öncə binary log-larımızı araşdıraq:

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000002 |       126 |
| mysql-bin.000003 |       126 |
| mysql-bin.000004 |      6969 |
| mysql-bin.000005 |       150 |
| mysql-bin.000006 |       710 |
+------------------+-----------+
5 rows in set (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000006 |      710 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Bu outputlardan aydın olur ki,bizim 6 ədəd binary log var. Və hal-hazırda istifadə olunanı da mysql-bin.000006-dır.

indi isə full logical backup:

[root@sh ~]# mysqldump -uroot -p --all-databases --single-transaction --flush-logs --master-data=2 > /home/shahriyar/dumps/full_logical_backup.sql
Enter password: 

1. –all-databases — bütün schema-ları çıxardır.
2. –single-transaction — bir transaction başladır və hər şeyi bir transaction-lar birdəfəlik yerinə yetirir.
–flush-logs — çox faydalı bir opsiya. backup-dan sonra yeni binary log yaradır. bu o deməkdir ki full backup-dan sonrakı bütün əməliyyatlar həmin bu yeni yaranan binary log-da qeyd olunur.
–master-data=2 — yeni yaranmış binary log kordinatlarını comment şəklində .sql faylına qeyd edəcək. indiki halda full_logical_backup.sql-a.
Və həqiqətən də faylı açdıqda ən başda bunu görəcik:

Yoxladıqda görürük ki həqiqətən də yeni binary log-umuz yaranıb:

Və davam edirik…bizim test_table-a gəlin əlavə 3 ədəd də insert verək:

mysql> insert into test_table(name,surname) values('Senan','Quliyev'),('Faxri','Xalidov'),('Elvin','Dursunov');
Query OK, 3 rows affected (0.23 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from test_table;
+----+-----------+----------+
| id | name      | surname  |
+----+-----------+----------+
|  1 | Shahriyar | Rzayev   |
|  2 | Khatai    | Rzayev   |
|  3 | Elvin     | Binyatov |
|  4 | Senan     | Quliyev  |
|  5 | Faxri     | Xalidov  |
|  6 | Elvin     | Dursunov |
+----+-----------+----------+
6 rows in set (0.00 sec)

Deməli belə, biz full backup aldıqdan sonra test_table cədvəlimizə əlavə 3 insert gedib. və son nəticədə bizdə 6 row olub. Burdan belə nəticə çıxarmaq olar ki, əgər faciə nəticəsində test_table drop olsa və sonra biz yaratdığımız .sql fayldan test_table-ı restore etsək bizim əlimizdə backup-dan əvvəlki 3 row olacaq elə deyil mi?
backup-dan sonrakı 3 row-nu isə birdəfəlik itirəcik? Qəşəng sualdı. itiriləcək row sayı 1000 olsa bəs onda necə?

Bir kənaraçıxma olsun bu: full logical backup almaq çox sadə görünsə də server-i yükləyə bilir.Mənim backup həcmim 517 mb oldu. Təbii ki production database-də bu 10 gb-lərlə ola bilər. İtiriləcək vaxtı nəzərə alın.
Bundan əlavə böyük .sql faylla işləmək olduqca çətindi və hər text editor bunu başarmır. Ən azından linux-da default olan gedit ümumiyyətlə donur. Mənim faylımı 20 dəqiqədən çox bir vaxtda aça bilmədi.
Bu əsasən o zaman problem olur ki, bizə bəlkə də full restore lazım olmadı bir cədvəli o boyda faylın içindən tapıb edit-ləmək təbii ki, əziyyətdir. Nə isə ki bunun üçün də bir çıxış yolu mövcuddur: GREP
SED

Və davam edirik. test_table-ı drop edirik:

mysql> drop table test_table;
Query OK, 0 rows affected (0.23 sec)

Indi isə full_logical_backup.sql fayl-ından yalnız test_table-ı restore edək.
ilk öncə sed vasitəsilə test_table-ın create-ni tapaq:

[root@sh dumps]# sed -e '/./{H;$!d;}' -e 'x;/CREATE TABLE `test_table`/!d;q' full_logical_backup.sql
DROP TABLE IF EXISTS `test_table`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `test_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(15) DEFAULT NULL,
  `surname` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

Və copy edib run edirik:

CREATE TABLE `test_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(15) DEFAULT NULL,
  `surname` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.19 sec)

grep vasitəsilə bizə lazım olan insertləri-i tapırıq və elə yerindəcə insert edirik:

[root@sh dumps]# grep 'INSERT INTO `test_table`' full_logical_backup.sql | mysql backup_test -u root -p
Enter password:

Və select:

mysql> select * from test_table;
+----+-----------+----------+
| id | name      | surname  |
+----+-----------+----------+
|  1 | Shahriyar | Rzayev   |
|  2 | Khatai    | Rzayev   |
|  3 | Elvin     | Binyatov |
+----+-----------+----------+
3 rows in set (0.00 sec)

Bəli ilk 3 row var amma digər son 3 row-nu itirmək istəmirəm deyirsinizsə. Çarəsi binary log
binary log-un aktiv edilməsi haqqında artıq yazım var:MySQL binary log-un aktiv edilməsi

Digər 3 row-nu da aşağıdakı qaydada bərpa edə bilərik. İlk öncə bizə lazım olan binary log-un içinə baxaq.bunun mysqlbinlog-dan istifadə olunur. və əgər nəzər alsaq ki bizə backup-dan sonrakı 3 insert lazımdır onu axtarıb tapmaq elə da çətin deyil:

[root@sh data]# mysqlbinlog mysql-bin.000008
.
.
# at 210
#121227 18:55:14 server id 1  end_log_pos 383 	Query	thread_id=2	exec_time=0	error_code=0
use backup_test/*!*/;
SET TIMESTAMP=1356620114/*!*/;
insert into test_table(name,surname) values('Senan','Quliyev'),('Faxri','Xalidov'),('Elvin','Dursunov')
/*!*/;
# at 383
#121227 18:55:14 server id 1  end_log_pos 410 	Xid = 9284
COMMIT/*!*/;
.
.

Burda əsas yadda saxlamalı olduğumuz at 210 və at 383…Yəni bizim restore-umuz başlıyacaq 210-dan bitəcək 383-də!

[root@sh data]# mysqlbinlog --start-position=210 --stop-position=383 /var/lib/mysql/data/mysql-bin.000008 | mysql -u root -p
Enter password: 

İnanmağınız üçün yoxlayaq:

mysql> select * from test_table;
+----+-----------+----------+
| id | name      | surname  |
+----+-----------+----------+
|  1 | Shahriyar | Rzayev   |
|  2 | Khatai    | Rzayev   |
|  3 | Elvin     | Binyatov |
|  4 | Senan     | Quliyev  |
|  5 | Faxri     | Xalidov  |
|  6 | Elvin     | Dursunov |
+----+-----------+----------+
6 rows in set (0.01 sec)

Sizi canı-könüldən təbrik edirəm itirilmiş 3 row bərpa olunmuşdur 🙂

Təbii ki bu binary log-un istifadəsinin sadə misalı idi. Amma elə burdan da görünür ki bu necə vacib bir məsələdir.
Binary log, Physical (Raw) backup, incremental backup, XtraBackup tool haqqında daha ətraflı yazılar olacaq. inşallah…
Hələlik isə beynəlxalq məsləhət. Production database-də yalnızca logical backup-la kifayətlənirsinzə,(Bizdə çox zaman bunu php script-lər vasitəsilə yerinə yetirirlər) O zaman heç olmasa mysqldump-dan istifadə edin.
Amma qətiyyən məsləhət görülməyən bir şeydir bu! Yalnızca logical backup yuxarıdakı sadə misalda göstərildiyi kimi məlumatların itirilməsinə gətirib çıxarır!
Mütləq şəkildə binary log-dan istifadə edin…məsələn həftədə 1 dəfə logical backup alın hər gün isə binary log ilə incremental backup alın. Yəni deyək ki, bazar günü full logical backup aldınız. Bazar ertəsi binary log1, bazar ertəsi binary log2, çərşənbə axşamı binary log3 və.s şəklində increment edin.
Ya da ki, hər 3 gündən bir full logical backup alın daha sonra binary log ilə increment edin və.s
Bu və digər metodlar haqqında yazılar olacaq.

Təşəkkürlər 🙂

MySQL binary log-un aktiv edilməsi

MySQL Binary log-u enable etmək istəyərkən mysql start olmadı. Başıma gələn bədbəxt hadisə sizə də olmasın deyə yazıram…
İlk öncə binary log nədir? From Documentation:
The binary log contains “events” that describe database changes such as table creation operations or changes to table data. It also contains events for statements that potentially could have made changes (for example, a DELETE which matched no rows), unless row-based logging is used. The binary log also contains information about how long each statement took that updated data

Və binary log-un 2 əsas yerdə istifadə olunur. Yenə də from Documentation:
The binary log has two important purposes:

1. For replication, the binary log on a master replication server provides a record of the data changes to be sent to slave servers. The master server sends the events contained in its binary log to its slaves, which execute those events to make the same data changes that were made on the master.

2. Certain data recovery operations require use of the binary log. After a backup has been restored, the events in the binary log that were recorded after the backup was made are re-executed. These events bring databases up to date from the point of the backup.

Bizim üçün indiki halda 2-ci bənd maraqlıdır. Qısaca onu deyim ki binary log vasitəsilə Point-in-Time (Incremental) Recovery icra olunur. MySQL backup and recovery haqqında mövzunu genişləndirəcəm təbii ki indiki halda sadəcə binary log-u necə enable edirlər ona baxırıq.

Deməli bunun üçün my.cnf faylına [mysqld] kataloqunun altından bunları yazırıq:

log_bin=/var/lib/mysql/data/mysql-bin
expire_logs_days=14
sync_binlog=1
binlog_format=row
log_bin_index=/var/lib/mysql/data/mysql-bin

1. log_bin=/var/lib/mysql/data/mysql-bin onu göstərir ki, bizim yaradılacaq binary log fayllarımızın adları mysql-bin-le başlayacaq. Məsələn mysql-bin.000003
2. log_bin_index=/var/lib/mysql/data/mysql-bin onu göstərir ki, mysql-bin.index adlı bir faylımız yaranacaq…bu fayl məqsədi: To keep track of which binary log files have been used, mysqld also creates a binary log index file that contains the names of all used binary log files..
3. expire_logs_days=14 hər 14 gündən bir köhnə binary log-lar avtomatik silinəcək.
4. sync_binlog=1 If the value of this variable is greater than 0, the MySQL server synchronizes its binary log to disk. Default qiymət =0-dır bu isə crash zamanı itkilərə yol aça bilər,ona görə də =1 yazmışıq.
5. binlog_format=row In row-based logging, the master writes events to the binary log that indicate how individual table rows are affected

my.cnf faylını Save edirik və mysql-i start etməyə çalışırıq.

[root@sh ~]# systemctl start mysqld.service
Job failed. See system journal and 'systemctl status' for details.

oops və dərhal log-a baxırıq:

/usr/libexec/mysqld: File '/var/lib/mysql/data/mysql-bin.000001' not found (Errcode: 13)
121225 22:29:02 [ERROR] Could not use /var/lib/mysql/data/mysql-bin for logging (error 13). Turning logging off for the whole duration of the MySQL server process. To turn it on again: fix the cause, shutdown the MySQL server and restart it.
121225 22:29:02 [ERROR] Aborting

Errorcode: 13
Vaxt itirmədən perror utility vasitəsilə bunun nə olduğuna baxırıq:

[root@sh ~]# perror 13
OS error code  13:  Permission denied

Permission denied bu bizə ipucu verir ki, problem MySQL-də yox məhz Linux-dadır yani OS imkan vermir ki MySQL /var/lib/mysql/data/ direktoriyasına nəsə yazsın.
Həlli:

[root@sh ~]# chown mysql:mysql /var/lib/mysql/data -R

MySQL-i start edirik:

[root@sh ~]# systemctl start mysqld.service

Və həqiqətən də ilk mysql-bin.000001 binary log-umuz yaradıldı.. Təbriklər 🙂

[root@sh ~]# ls /var/lib/mysql/data
mysql-bin.000001  mysql-bin.index  sh-slow.log