Below is the list of changes that have just been committed into a local
6.0 repository of rafal. When rafal does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-30 09:23:34+01:00, rafal@quant.(none) +26 -0
WL#4060 (kernel updates for beta release):
This patch modifies backup kernel code so that it uses the backup stream library
for writing and reading backup images. Now backup kernel writes backup images in
the format described in WL#4063.
Limitations:
1. Errors are detected but not always reported in the error log - only a general
error message will be shown.
2. Object names using non-standard charsets are still not supported. The code
doesn't address this issue yet.
3. The default server charset is stored in the image, but it is not set upon
restore. This should not be a big problem however, since I believe that CREATE
TABLE statements we use always set charset and collaction explicitly.
4. I don't obtain CREATE DATABASE statements from the server and thus don't save
things like default charset or collation. It should be easy to add but I simply
didn't have time to do it now. There is a bug entry for this.
5. The summary produced by BACKUP/RESTORE commands is now very minimalistic. Due
to complex buffering in the backup stream library it is difficult to get exact
sizes of various parts of the backup image and thus produce similar summary as
before. Since format of the summary is going to change soon, I didn't spend time
on improving it.
6. Eventually, the endianess of the server which created backup image should be
stored in image flags. This code doesn't store this information (as I'm not sure
how to get it). Note however that the image format *is* endianess agnostic (at
least the part written by the kernel). The purpose of the flag is to provide
more information for the user and possibly for restore drivers (not supported in
the current driver API).
BitKeeper/deleted/.del-map.h~3bf2f96a8cb7ffe7@stripped, 2007-11-30 09:21:40+01:00,
rafal@quant.(none) +0 -0
Rename: sql/backup/map.h -> BitKeeper/deleted/.del-map.h~3bf2f96a8cb7ffe7
BitKeeper/deleted/.del-string_pool.cc~52288457d3ba0e49@stripped, 2007-11-30 09:21:40+01:00,
rafal@quant.(none) +0 -0
Rename: sql/backup/string_pool.cc ->
BitKeeper/deleted/.del-string_pool.cc~52288457d3ba0e49
BitKeeper/deleted/.del-string_pool.h~c9ae95ef8972eaf9@stripped, 2007-11-30 09:21:41+01:00,
rafal@quant.(none) +0 -0
Rename: sql/backup/string_pool.h ->
BitKeeper/deleted/.del-string_pool.h~c9ae95ef8972eaf9
mysql-test/r/backup.result@stripped, 2007-11-30 09:23:28+01:00, rafal@quant.(none) +12 -20
Result changes due to different BACKUP/RESTORE summary.
mysql-test/r/backup_commit_blocker.result@stripped, 2007-11-30 09:23:28+01:00,
rafal@quant.(none) +18 -30
Result changes due to different BACKUP/RESTORE summary.
mysql-test/r/backup_no_data.result@stripped, 2007-11-30 09:23:28+01:00, rafal@quant.(none)
+21 -35
Result changes due to different BACKUP/RESTORE summary.
mysql-test/r/backup_no_engine.result@stripped, 2007-11-30 09:23:28+01:00, rafal@quant.(none)
+6 -10
Result changes due to different BACKUP/RESTORE summary.
mysql-test/r/backup_security.result@stripped, 2007-11-30 09:23:28+01:00, rafal@quant.(none)
+12 -20
Result changes due to different BACKUP/RESTORE summary.
mysql-test/r/backup_snapshot.result@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none)
+12 -20
Result changes due to different BACKUP/RESTORE summary.
sql/backup/CMakeLists.txt@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +3 -2
- remove string_pool.cc which is no longer used;
- add backupstream library to the backup library.
sql/backup/Makefile.am@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +6 -4
- removed sources and headers which are not used now
- added be_native.h header
- added libbackupstream to libbackup
sql/backup/backup_aux.h@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +133 -0
- added new constructor for backup::LEX_STRING
- added backup::String convenience class
- added backup::Dynamic_array class template
sql/backup/backup_kernel.h@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +58 -67
Updated declarations of the Backup_info and Restore_info classes.
sql/backup/backup_stream.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +15 -0
New header which defines the backup stream format used.
sql/backup/backup_stream.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +0 -0
sql/backup/be_default.h@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +10 -18
Updated definition of Default_image class, now called Default_snapshot.
sql/backup/be_native.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +74 -0
Definition of the Native_snapshot class using when backing-up/restoring table
data using native backup engines.
sql/backup/be_native.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +0 -0
sql/backup/be_snapshot.h@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +11 -19
Changed definition of Snapshot_image class, now called CS_snapshot.
sql/backup/catalog.cc@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +148 -732
Changed implementation of Archive_info, now called Image_info. Now this class
doesn't contain any code for writing parts of backup image. Instead, backup
stream library functions are called and the class collects all information
needed for them.
This file also implements the catalogue services needed by the backup stream
library (bcat_*() functions).
sql/backup/catalog.h@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +611 -328
New definition of Archive_info class, now called Image_info and former
Image_info, now called Snapshot_info.
sql/backup/data_backup.cc@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +184 -213
Use bstream_rd_table_data() and bstream_wr_table_data() for reading/writng table
data blocks. This is done in restore_table_data() function and
Block_writer::write_buf() method.
sql/backup/kernel.cc@stripped, 2007-11-30 09:23:29+01:00, rafal@quant.(none) +840 -450
- cosmetic changes to execute_backup_command();
- new implementations of Backup_info and Restore_info classes
- implementation of rstore-time catalogue services for backup stream library
- memory allocation for backup stream library
sql/backup/meta_data.cc@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +93 -283
- meta-data manipulating services for backup stream library.
- definitions of meta::Item and derived classes for manipulationg object
meta-data
sql/backup/meta_data.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +49 -60
Updated definitions of meta::Item and derived classes to make them suitable for
implementing services needed by backup stream library. Methods for
writing/reading meta-data are removes since now the library functions are used
for that purpose (this is done inside bstream_{wr,rd}_meta_data())
sql/backup/stream.cc@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +249 -205
Changed definitions of IStream and OStream classes. Now they implement the
"abstract stream" used by the backup stream library to read/write data.
sql/backup/stream.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +39 -586
- removed old code for writing/reading backup stream;
- updated definitions of the IStream/OStream classes.
sql/backup/stream_services.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +10 -0
New header file defining current version of stream services implemented in the
backup kernel.
sql/backup/stream_services.h@stripped, 2007-11-30 09:23:30+01:00, rafal@quant.(none) +0 -0
diff -Nrup a/mysql-test/r/backup.result b/mysql-test/r/backup.result
--- a/mysql-test/r/backup.result 2007-11-09 22:32:08 +01:00
+++ b/mysql-test/r/backup.result 2007-11-30 09:23:28 +01:00
@@ -57,21 +57,17 @@ INSERT INTO `tasking` VALUES ('333445555
UNLOCK TABLES;
BACKUP DATABASE db1,db2 TO 'test.ba';
Backup Summary
- header = 52 bytes
- meta-data = 807 bytes
- data = 639 bytes
- --------------
- total 1498 bytes
+ backed up 4 tables
+ in 2 databases
+ using 1 driver
DROP DATABASE db1;
DROP DATABASE db2;
USE mysql;
RESTORE FROM 'test.ba';
Restore Summary
- header = 52 bytes
- meta-data = 807 bytes
- data = 639 bytes
- --------------
- total 1498 bytes
+ restored 4 tables
+ in 2 databases
+ using 1 driver
USE db1;
SHOW TABLES;
Tables_in_db1
@@ -319,19 +315,15 @@ Chuck@linux:~> mysql -uroot -p
Enter password:
BACKUP DATABASE bup_default TO "bup_default.bak";
Backup Summary
- header = 43 bytes
- meta-data = 890 bytes
- data = 7368 bytes
- --------------
- total 8301 bytes
+ backed up 4 tables
+ in 1 database
+ using 2 drivers
DROP DATABASE bup_default;
RESTORE FROM "bup_default.bak";
Restore Summary
- header = 43 bytes
- meta-data = 890 bytes
- data = 7368 bytes
- --------------
- total 8301 bytes
+ restored 4 tables
+ in 1 database
+ using 2 drivers
SELECT * FROM bup_default.t1;
a
1
diff -Nrup a/mysql-test/r/backup_commit_blocker.result
b/mysql-test/r/backup_commit_blocker.result
--- a/mysql-test/r/backup_commit_blocker.result 2007-11-16 02:29:32 +01:00
+++ b/mysql-test/r/backup_commit_blocker.result 2007-11-30 09:23:28 +01:00
@@ -86,11 +86,9 @@ UPDATE bup_commit_blocker.t3 SET col_a =
UPDATE bup_commit_blocker.t3 SET col_a = "con4: 06 CHANGED" WHERE col_a LIKE '06%';
COMMIT;
Backup Summary
- header = 36 bytes
- meta-data = 284 bytes
- data = 471 bytes
- --------------
- total 791 bytes
+ backed up 3 tables
+ in 1 database
+ using 1 driver
con1: Showing data after updates and backup
SELECT * FROM bup_commit_blocker.t1;
col_a
@@ -121,11 +119,9 @@ DROP TABLE bup_commit_blocker.t3;
con1: Restoring the database
RESTORE FROM "bup_commit_blocker.bak";
Restore Summary
- header = 36 bytes
- meta-data = 284 bytes
- data = 471 bytes
- --------------
- total 791 bytes
+ restored 3 tables
+ in 1 database
+ using 1 driver
con1: Showing the data (no new data should be here).
SELECT * FROM bup_commit_blocker.t1;
col_a
@@ -217,11 +213,9 @@ NULL
con6: Completing statement
con7: Completing statement
Backup Summary
- header = 28 bytes
- meta-data = 95 bytes
- data = 50 bytes
- --------------
- total 173 bytes
+ backed up 1 tables
+ in 1 database
+ using 1 driver
con1: Showing data after updates and backup
SELECT * FROM bup_commit_blocker.t5;
col_a
@@ -235,11 +229,9 @@ DROP TABLE bup_commit_blocker.t5;
con1: Restoring the database
RESTORE FROM "bup_commit_blocker.bak";
Restore Summary
- header = 28 bytes
- meta-data = 95 bytes
- data = 50 bytes
- --------------
- total 173 bytes
+ restored 1 tables
+ in 1 database
+ using 1 driver
con1: Showing the data (no new data should be here).
SELECT * FROM bup_commit_blocker.t5;
col_a
@@ -367,11 +359,9 @@ UPDATE bup_commit_blocker.t3 SET col_a =
COMMIT;
con7: Completing statement
Backup Summary
- header = 43 bytes
- meta-data = 377 bytes
- data = 521 bytes
- --------------
- total 941 bytes
+ backed up 4 tables
+ in 1 database
+ using 2 drivers
con1: Showing data after updates and backup
SELECT * FROM bup_commit_blocker.t1;
col_a
@@ -409,11 +399,9 @@ DROP TABLE bup_commit_blocker.t5;
con1: Restoring the database
RESTORE FROM "bup_commit_blocker.bak";
Restore Summary
- header = 43 bytes
- meta-data = 377 bytes
- data = 521 bytes
- --------------
- total 941 bytes
+ restored 4 tables
+ in 1 database
+ using 2 drivers
con1: Showing the data (no new data should be here).
SELECT * FROM bup_commit_blocker.t1;
col_a
diff -Nrup a/mysql-test/r/backup_no_data.result b/mysql-test/r/backup_no_data.result
--- a/mysql-test/r/backup_no_data.result 2007-11-06 19:32:23 +01:00
+++ b/mysql-test/r/backup_no_data.result 2007-11-30 09:23:28 +01:00
@@ -2,18 +2,14 @@ DROP DATABASE IF EXISTS empty_db;
CREATE DATABASE empty_db;
BACKUP DATABASE empty_db TO 'empty_db.bak';
Backup Summary
- header = 11 bytes
- meta-data = 2 bytes
- data = 0 bytes
- --------------
- total 13 bytes
+ backed up 0 tables
+ in 1 database
+ using 0 driver
BACKUP DATABASE * TO 'all.bak';
Backup Summary
- header = 16 bytes
- meta-data = 4 bytes
- data = 0 bytes
- --------------
- total 20 bytes
+ backed up 0 tables
+ in 2 databases
+ using 0 driver
DROP DATABASE empty_db;
DROP DATABASE test;
SHOW DATABASES;
@@ -26,11 +22,9 @@ information_schema
mysql
RESTORE FROM 'all.bak';
Restore Summary
- header = 16 bytes
- meta-data = 4 bytes
- data = 0 bytes
- --------------
- total 20 bytes
+ restored 0 tables
+ in 2 databases
+ using 0 driver
SHOW DATABASES;
Database
information_schema
@@ -41,11 +35,9 @@ DROP DATABASE empty_db;
DROP DATABASE test;
RESTORE FROM 'empty_db.bak';
Restore Summary
- header = 11 bytes
- meta-data = 2 bytes
- data = 0 bytes
- --------------
- total 13 bytes
+ restored 0 tables
+ in 1 database
+ using 0 driver
SHOW DATABASES;
Database
information_schema
@@ -55,11 +47,9 @@ SHOW TABLES IN empty_db;
Tables_in_empty_db
RESTORE FROM 'all.bak';
Restore Summary
- header = 16 bytes
- meta-data = 4 bytes
- data = 0 bytes
- --------------
- total 20 bytes
+ restored 0 tables
+ in 2 databases
+ using 0 driver
SHOW DATABASES;
Database
information_schema
@@ -81,11 +71,9 @@ DROP VIEW IF EXISTS v1;
CREATE VIEW v1 AS SELECT * FROM test.t1;
BACKUP DATABASE empty_db TO 'empty_db.bak';
Backup Summary
- header = 11 bytes
- meta-data = 2 bytes
- data = 0 bytes
- --------------
- total 13 bytes
+ backed up 0 tables
+ in 1 database
+ using 0 driver
SHOW DATABASES;
Database
information_schema
@@ -94,11 +82,9 @@ mysql
test
RESTORE FROM 'empty_db.bak';
Restore Summary
- header = 11 bytes
- meta-data = 2 bytes
- data = 0 bytes
- --------------
- total 13 bytes
+ restored 0 tables
+ in 1 database
+ using 0 driver
USE empty_db;
SHOW TABLES;
Tables_in_empty_db
diff -Nrup a/mysql-test/r/backup_no_engine.result b/mysql-test/r/backup_no_engine.result
--- a/mysql-test/r/backup_no_engine.result 2007-11-06 19:32:23 +01:00
+++ b/mysql-test/r/backup_no_engine.result 2007-11-30 09:23:28 +01:00
@@ -4,20 +4,16 @@ CREATE TABLE db.t1 (a int, b char(32))
ENGINE=myisam;
BACKUP DATABASE db TO "db.backup";
Backup Summary
- header = 12 bytes
- meta-data = 120 bytes
- data = 0 bytes
- --------------
- total 132 bytes
+ backed up 1 tables
+ in 1 database
+ using 1 driver
DROP DATABASE db;
CREATE DATABASE db;
RESTORE FROM "db.backup";
Restore Summary
- header = 12 bytes
- meta-data = 120 bytes
- data = 0 bytes
- --------------
- total 132 bytes
+ restored 1 tables
+ in 1 database
+ using 1 driver
SHOW TABLES IN db;
Tables_in_db
t1
diff -Nrup a/mysql-test/r/backup_security.result b/mysql-test/r/backup_security.result
--- a/mysql-test/r/backup_security.result 2007-11-09 22:32:08 +01:00
+++ b/mysql-test/r/backup_security.result 2007-11-30 09:23:28 +01:00
@@ -19,11 +19,9 @@ GRANT SUPER ON *.* TO 'bup_with_rights'@
default: Do backup of database with default test user for later tests.
BACKUP DATABASE backup_test to 'backup_test_orig.bak';
Backup Summary
- header = 21 bytes
- meta-data = 92 bytes
- data = 245 bytes
- --------------
- total 358 bytes
+ backed up 1 tables
+ in 1 database
+ using 1 driver
default: Connect as user with no rights and attempt backup and restore.
no_rights: Attempting backup. Should fail with error 1227
BACKUP DATABASE backup_test to 'bup_no_rights.bak';
@@ -50,19 +48,15 @@ Connect as user with rights and attempt
no_rights: Attempting backup. Should succeed
BACKUP DATABASE backup_test to 'bup_with_rights.bak';
Backup Summary
- header = 21 bytes
- meta-data = 92 bytes
- data = 245 bytes
- --------------
- total 358 bytes
+ backed up 1 tables
+ in 1 database
+ using 1 driver
no_rights: Attempting restore. Should succeed
RESTORE FROM 'bup_with_rights.bak';
Restore Summary
- header = 21 bytes
- meta-data = 92 bytes
- data = 245 bytes
- --------------
- total 358 bytes
+ restored 1 tables
+ in 1 database
+ using 1 driver
SELECT * FROM t1;
a
01 Test #1 - super privilege
@@ -75,11 +69,9 @@ a
default: Do restore to ensure it still works with default test user.
RESTORE FROM 'backup_test_orig.bak';
Restore Summary
- header = 21 bytes
- meta-data = 92 bytes
- data = 245 bytes
- --------------
- total 358 bytes
+ restored 1 tables
+ in 1 database
+ using 1 driver
SELECT * FROM t1;
a
01 Test #1 - super privilege
diff -Nrup a/mysql-test/r/backup_snapshot.result b/mysql-test/r/backup_snapshot.result
--- a/mysql-test/r/backup_snapshot.result 2007-11-16 02:29:25 +01:00
+++ b/mysql-test/r/backup_snapshot.result 2007-11-30 09:23:29 +01:00
@@ -36,11 +36,9 @@ SELECT release_lock("backup_cs_locked");
release_lock("backup_cs_locked")
1
Backup Summary
- header = 29 bytes
- meta-data = 184 bytes
- data = 320 bytes
- --------------
- total 533 bytes
+ backed up 2 tables
+ in 1 database
+ using 2 drivers
INSERT INTO bup_snapshot.t1 VALUES("- Yes");
INSERT INTO bup_snapshot.t1 VALUES("- Jethro Tull");
DELETE FROM bup_snapshot.t1 WHERE word LIKE '10%';
@@ -58,11 +56,9 @@ DROP TABLE bup_snapshot.t1;
con1: Restoring the database
RESTORE FROM "bup_snapshot.bak";
Restore Summary
- header = 29 bytes
- meta-data = 184 bytes
- data = 320 bytes
- --------------
- total 533 bytes
+ restored 2 tables
+ in 1 database
+ using 2 drivers
con1: Showing the data (no new data should be here).
SELECT * FROM bup_snapshot.t1 WHERE word LIKE '-%';
word
@@ -98,21 +94,17 @@ SELECT COUNT(*) FROM bup_snapshot.t1;
COUNT(*)
12
Backup Summary
- header = 29 bytes
- meta-data = 184 bytes
- data = 320 bytes
- --------------
- total 533 bytes
+ backed up 2 tables
+ in 1 database
+ using 2 drivers
con1: Dropping the database
DROP TABLE bup_snapshot.t1;
con1: Restoring the database
RESTORE FROM "bup_snapshot.bak";
Restore Summary
- header = 29 bytes
- meta-data = 184 bytes
- data = 320 bytes
- --------------
- total 533 bytes
+ restored 2 tables
+ in 1 database
+ using 2 drivers
con1: Showing the data (no new data should be here).
SELECT * FROM bup_snapshot.t1 WHERE word LIKE '-%';
word
diff -Nrup a/sql/backup/CMakeLists.txt b/sql/backup/CMakeLists.txt
--- a/sql/backup/CMakeLists.txt 2007-11-29 20:34:05 +01:00
+++ b/sql/backup/CMakeLists.txt 2007-11-30 09:23:29 +01:00
@@ -22,9 +22,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include)
-SET(BACKUP_SOURCES stream.cc logger.cc string_pool.cc
+SET(BACKUP_SOURCES stream.cc logger.cc kernel.cc
catalog.cc meta_data.cc data_backup.cc
- kernel.cc be_default.cc buffer_iterator.cc
+ be_default.cc buffer_iterator.cc
be_snapshot.cc be_thread.cc)
IF(NOT SOURCE_SUBLIBS)
@@ -32,5 +32,6 @@ IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(backupstream stream_v1.c stream_v1_transport.c)
ENDIF(NOT SOURCE_SUBLIBS)
+TARGET_LINK_LIBRARIES(backup backupstream)
ADD_DEPENDENCIES(backup mysys)
diff -Nrup a/sql/backup/Makefile.am b/sql/backup/Makefile.am
--- a/sql/backup/Makefile.am 2007-11-29 20:34:05 +01:00
+++ b/sql/backup/Makefile.am 2007-11-30 09:23:29 +01:00
@@ -28,16 +28,17 @@ INCLUDES = \
libbackup_la_SOURCES = \
stream.cc \
logger.cc \
- string_pool.cc \
catalog.cc \
+ kernel.cc \
meta_data.cc \
data_backup.cc \
- kernel.cc \
be_default.cc \
be_snapshot.cc \
buffer_iterator.cc \
be_thread.cc
+libbackup_la_LIBADD = libbackupstream.la
+
libbackupstream_la_SOURCES= \
stream_v1_transport.c \
stream_v1.c
@@ -46,15 +47,16 @@ noinst_HEADERS = \
api_types.h \
backup_engine.h \
backup_kernel.h \
+ backup_stream.h \
+ stream_services.h \
debug.h \
error.h \
stream.h \
backup_aux.h \
logger.h \
- map.h \
- string_pool.h \
catalog.h \
meta_data.h \
+ be_native.h \
be_default.h \
be_snapshot.h \
buffer_iterator.h \
diff -Nrup a/sql/backup/backup_aux.h b/sql/backup/backup_aux.h
--- a/sql/backup/backup_aux.h 2007-11-29 20:34:05 +01:00
+++ b/sql/backup/backup_aux.h 2007-11-30 09:23:29 +01:00
@@ -2,6 +2,7 @@
#define _BACKUP_AUX_H
#include <backup/api_types.h>
+#include <backup_stream.h>
namespace backup {
@@ -35,8 +36,135 @@ struct LEX_STRING: public ::LEX_STRING
str= const_cast<char*>(s.ptr());
length= s.length();
}
+
+ LEX_STRING(byte *begin, byte *end)
+ {
+ str= (char*)begin;
+ if( begin && end > begin)
+ length= end - begin;
+ else
+ length= 0;
+ }
};
+class String: public ::String
+{
+ public:
+
+ String(const ::String &s): ::String(s)
+ {}
+
+ String(const ::LEX_STRING &s):
+ ::String(s.str,s.length,&::my_charset_bin) // FIXME: charset info
+ {}
+
+ String(byte *begin, byte *end):
+ ::String((char*)begin,end-begin,&::my_charset_bin) // FIXME: charset info
+ {
+ if (!begin)
+ set((char*)NULL,0,NULL);
+ }
+
+ String(const char *s):
+ ::String(s,&::my_charset_bin)
+ {}
+
+ String(): ::String()
+ {}
+};
+
+
+/*
+
+ Dynamic_array<Foo> array;
+
+ new (array.get_entry(7)) Foo(....);
+
+ if (foo = array[7])
+ {
+ foo->...
+ }
+
+ TODO: Look at similar class in sql_array.h
+*/
+
+template<class X>
+class Dynamic_array
+{
+ ::DYNAMIC_ARRAY m_array;
+
+ public:
+
+ Dynamic_array(uint init_size, uint alloc_increment)
+ {
+ my_init_dynamic_array(&m_array,1+sizeof(X),init_size,alloc_increment);
+ clear_free_space();
+ }
+
+ ~Dynamic_array()
+ {
+ for (uint pos=0; pos < m_array.elements; ++pos)
+ {
+ X *ptr= const_cast<X*>((*this)[pos]);
+ if (ptr)
+ ptr->~X();
+ }
+
+ delete_dynamic(&m_array);
+ }
+
+ X* operator[](uint pos) const
+ {
+ if (pos >= m_array.elements)
+ return NULL;
+
+ uchar *ptr= dynamic_array_ptr(&m_array,pos);
+
+ return *ptr == 0xFF ? (X*)(ptr+1) : NULL;
+ }
+
+ X* get_entry(uint pos)
+ {
+ uchar *entry;
+
+ while (pos > m_array.max_element)
+ {
+ entry= alloc_dynamic(&m_array);
+ if (!entry)
+ break;
+ }
+
+ clear_free_space();
+
+ if (pos > m_array.max_element)
+ return NULL;
+
+ if (pos >= m_array.elements)
+ m_array.elements= pos+1;
+
+ entry= dynamic_array_ptr(&m_array,pos);
+ X *ptr= (X*)(entry+1);
+
+ if (*entry == 0xFF)
+ ptr->~X();
+
+ *entry= 0xFF;
+ return new (ptr) X();
+ }
+
+ uint size() const
+ { return m_array.elements; }
+
+ private:
+
+ void clear_free_space()
+ {
+ uchar *start= dynamic_array_ptr(&m_array,m_array.elements);
+ uchar *end= dynamic_array_ptr(&m_array,m_array.max_element);
+ if (end > start)
+ bzero(start, end - start);
+ }
+};
TABLE_LIST *build_table_list(const Table_list&,thr_lock_type);
@@ -76,6 +204,11 @@ inline int free_table_list(TABLE_LIST *a
}
return 0;
}
+
+// These functions are implemented in kernel.cc
+
+int silent_exec_query(THD*, ::String&);
+void save_current_time(bstream_time_t &buf);
} // backup namespace
diff -Nrup a/sql/backup/backup_kernel.h b/sql/backup/backup_kernel.h
--- a/sql/backup/backup_kernel.h 2007-11-29 20:34:05 +01:00
+++ b/sql/backup/backup_kernel.h 2007-11-30 09:23:29 +01:00
@@ -3,26 +3,30 @@
#include <backup/api_types.h>
#include <backup/catalog.h>
-#include <backup/stream.h>
#include <backup/logger.h>
-
-/*
- Called from the big switch in mysql_execute_command() to execute
- backup related statement
- */
-int execute_backup_command(THD*, LEX*);
-
/**
@file
Functions and types forming the backup kernel API
+*/
- */
+
+/**
+ @brief Size of the buffer used for transfers between backup kernel and
+ backup/restore drivers.
+*/
+#define DATA_BUFFER_SIZE (1024*1024)
+
+/*
+ Called from the big switch in mysql_execute_command() to execute
+ backup related statement
+*/
+int execute_backup_command(THD*, LEX*);
namespace backup {
-class Archive_info;
+class Image_info;
class Backup_info;
class Restore_info;
@@ -30,7 +34,6 @@ class Restore_info;
// Backup kernel API
-int mysql_show_archive(THD*,const backup::Archive_info&);
int mysql_backup(THD*, backup::Backup_info&, backup::OStream&);
int mysql_restore(THD*, backup::Restore_info&, backup::IStream&);
@@ -77,7 +80,7 @@ struct Location
/**
- Specialization of @c Archive_info which adds methods for selecting items
+ Specialization of @c Image_info which adds methods for selecting items
to backup.
When Backup_info object is created it is empty and ready for adding items
@@ -86,20 +89,9 @@ struct Location
supported). After populating info object with items it should be "closed"
with a call to @c close() method. After that it is ready for use as a
description of backup archive to be created.
-
- A linked list of all meta-data items is pointed by @c m_items member. It
- consists of three parts: first all the global items, then all per-database
- items and finally all per-table items. Inside each part, items are stored in
- dependency order so that if item A depends on B then B is before A in the
- list (currently dependencies are not checked). One should iterate through the
- meta-data item list using @c Backup_info::Item_iterator class.
- */
-
-class Backup_info: public Archive_info, public Logger
+*/
+class Backup_info: public Image_info, public Logger
{
- class Table_ref;
- class Db_ref;
-
public:
Backup_info(THD*);
@@ -129,15 +121,11 @@ class Backup_info: public Archive_info,
return ok;
}
- int save(OStream&);
-
int add_dbs(List< ::LEX_STRING >&);
int add_all_dbs();
bool close();
- class Item_iterator; // for iterating over all meta-data items
-
private:
/// State of the info structure.
@@ -147,67 +135,64 @@ class Backup_info: public Archive_info,
ERROR
} m_state;
- int find_image(const Table_ref&);
-
- int default_image_no; ///< Position of the default image in @c images list, -1 if
not used.
- int snapshot_image_no; ///< Position of the snapshot image in @c images list, -1 if
not used.
+ int find_backup_engine(const ::TABLE *const, const Table_ref&);
- Db_item* add_db(const backup::Db_ref&);
- Table_item* add_table(const Table_ref&);
-
- /// Value returned by @c add_table if it decides that the table should be skipped.
- static const Table_item *const skip_table;
+ Table_item* add_table(Db_item&, const Table_ref&);
int add_db_items(Db_item&);
int add_table_items(Table_item&);
THD *m_thd;
TABLE *i_s_tables;
+ String binlog_file_name; ///< stores name of the binlog at VP time
- Item *m_items;
- Item *m_last_item;
- Item *m_last_db;
+ /**
+ @brief Storage for table and database names.
- friend class Item_iterator;
-};
+ When adding tables or databases to the backup catalogue, their names
+ are stored in String objects, and these objects are appended to this
+ list so that they can be freed when Backup_info object is destroyed.
+ */
+ // FIXME: use better solution, e.g., MEM_ROOT
+ List<String> name_strings;
-class Backup_info::Item_iterator: public Archive_info::Item::Iterator
-{
- public:
- Item_iterator(const Backup_info &info):
- Archive_info::Item::Iterator(info.m_items)
- {}
+ void save_binlog_pos(const ::LOG_INFO &li)
+ {
+ binlog_file_name= li.log_file_name;
+ binlog_file_name.copy();
+ binlog_pos.pos= li.pos;
+ binlog_pos.file= binlog_file_name.c_ptr();
+ }
+
+ friend int write_table_data(THD*, Backup_info&, OStream&);
};
+
/**
- Specialization of @c Archive_info which is used to select and restore items
- from a backup archive.
+ Specialization of @c Image_info which is used to select and restore items
+ from a backup image.
- An instance of this class is created by reading backup archive header and it
- describes contents of the archive. @c Restore_info methods select which items
- should be restored. Instances of @c Restore_info::Item class are created when
- reading meta-data info stored in the archive. They are used to restore the
- meta-data items (but not the table data, which is done by restore drivers).
+ An instance of this class is created by reading backup image header and it
+ describes its contents. @c Restore_info methods select which items
+ should be restored.
@note This class is not fully implemented. Right now it is not possible to
select items to restore - always all items are restored.
*/
-class Restore_info: public Archive_info, public Logger
+class Restore_info: public Image_info, public Logger
{
bool m_valid;
+ THD *m_thd;
+ const Db_ref *curr_db;
+
+ CHARSET_INFO *system_charset;
+ bool same_sys_charset;
public:
- Restore_info(IStream &s): Logger(Logger::RESTORE), m_valid(TRUE)
- {
- result_t res= read(s);
- if (res == ERROR)
- {
- report_error(ER_BACKUP_READ_HEADER);
- m_valid= FALSE;
- }
- }
+ Restore_info(THD*, IStream&);
+ ~Restore_info();
bool is_valid() const
{ return m_valid; }
@@ -216,8 +201,14 @@ class Restore_info: public Archive_info,
{ return 0; }
/// Determine if given item is selected for restore.
- bool selected(const Archive_info::Item&)
+ bool selected(const Image_info::Item&)
{ return TRUE; }
+
+ result_t restore_item(Item&, ::String&, byte*, byte*);
+
+ friend int restore_table_data(THD*, Restore_info&, IStream&);
+ friend int ::bcat_add_item(st_bstream_image_header*,
+ struct st_bstream_item_info*);
};
} // backup namespace
diff -Nrup a/sql/backup/backup_stream.h b/sql/backup/backup_stream.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/sql/backup/backup_stream.h 2007-11-30 09:23:30 +01:00
@@ -0,0 +1,15 @@
+#ifndef BACKUP_STREAM_H_
+#define BACKUP_STREAM_H_
+
+// magic bytes defined in stream.cc
+extern const unsigned char backup_magic_bytes[8];
+
+extern "C" {
+
+// We use version 1 of the stream format.
+
+#include "stream_v1.h"
+
+}
+
+#endif /*BACKUP_STREAM_H_*/
diff -Nrup a/sql/backup/be_default.h b/sql/backup/be_default.h
--- a/sql/backup/be_default.h 2007-11-29 20:34:05 +01:00
+++ b/sql/backup/be_default.h 2007-11-30 09:23:29 +01:00
@@ -200,22 +200,24 @@ class Restore: public Restore_driver
/*********************************************************************
- Default image class
+ Default snapshot class
*********************************************************************/
namespace backup {
-class Default_image: public Image_info
+class Default_snapshot: public Snapshot_info
{
public:
- Default_image(Archive_info &info): Image_info(info)
- { ver= 1; }
+ Default_snapshot()
+ {
+ version= 1;
+ }
- image_type type() const
- { return DEFAULT_IMAGE; }
+ enum_snap_type type() const
+ { return DEFAULT_SNAPSHOT; }
const char* name() const
{ return "Default"; }
@@ -224,21 +226,11 @@ class Default_image: public Image_info
{ return TRUE; }; // accept all tables
result_t get_backup_driver(Backup_driver* &ptr)
- { return (ptr= new default_backup::Backup(tables,::current_thd,
+ { return (ptr= new default_backup::Backup(m_tables,::current_thd,
TL_READ_NO_INSERT)) ? OK : ERROR; }
result_t get_restore_driver(Restore_driver* &ptr)
- { return (ptr= new default_backup::Restore(tables,::current_thd)) ? OK : ERROR; }
-
- result_t do_write_description(OStream&)
- { return OK; } // nothing to write
-
- static result_t
- create_from_stream(version_t, Archive_info &info, IStream&,
- Image_info* &ptr)
- {
- return (ptr= new Default_image(info)) ? OK : ERROR;
- }
+ { return (ptr= new default_backup::Restore(m_tables,::current_thd)) ? OK : ERROR; }
bool is_valid(){ return TRUE; };
diff -Nrup a/sql/backup/be_native.h b/sql/backup/be_native.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/sql/backup/be_native.h 2007-11-30 09:23:30 +01:00
@@ -0,0 +1,74 @@
+#ifndef BE_NATIVE_H_
+#define BE_NATIVE_H_
+
+#include <backup_engine.h>
+
+namespace backup {
+
+/**
+ Specialization of @c Image_info for images created by native backup drivers.
+ */
+class Native_snapshot: public Snapshot_info
+{
+ const ::handlerton *m_hton; ///< Pointer to storage engine.
+ Engine *m_be; ///< Pointer to the native backup engine.
+ const char *m_name; ///< Saved name of storage engine.
+ unsigned int se_ver; ///< Storage engine version number.
+
+ public:
+
+ Native_snapshot(const ::plugin_ref se): m_hton(NULL), m_be(NULL)
+ {
+ m_hton= plugin_data(se,::handlerton*);
+ se_ver= (*se)->plugin->version;
+
+ DBUG_ASSERT(m_hton);
+ DBUG_ASSERT(m_hton->get_backup_engine);
+
+ result_t ret= m_hton->get_backup_engine(const_cast< ::handlerton*
>(m_hton),m_be);
+
+ if (ret != OK || !m_be)
+ return;
+
+ version= m_be->version();
+ m_name= ::ha_resolve_storage_engine_name(m_hton);
+ }
+
+ ~Native_snapshot()
+ {
+ if (m_be)
+ m_be->free();
+ }
+
+ bool is_valid()
+ { return m_be != NULL; }
+
+ enum_snap_type type() const
+ { return NATIVE_SNAPSHOT; }
+
+ const char* name() const
+ { return m_name; }
+
+ bool accept(const Table_ref&, const ::handlerton *hton)
+ { return hton == m_hton; }; // this assumes handlertons are single instance objects!
+
+ result_t get_backup_driver(Backup_driver* &drv)
+ {
+ DBUG_ASSERT(m_be);
+ return m_be->get_backup(Driver::PARTIAL,m_tables,drv);
+ }
+
+ result_t get_restore_driver(Restore_driver* &drv)
+ {
+ DBUG_ASSERT(m_be);
+ return m_be->get_restore(version,Driver::PARTIAL,m_tables,drv);
+ }
+
+ friend void save_snapshot_info(const Snapshot_info&,
+ st_bstream_snapshot_info&);
+};
+
+
+} // backup namespace
+
+#endif /*BE_NATIVE_H_*/
diff -Nrup a/sql/backup/be_snapshot.h b/sql/backup/be_snapshot.h
--- a/sql/backup/be_snapshot.h 2007-11-29 20:34:05 +01:00
+++ b/sql/backup/be_snapshot.h 2007-11-30 09:23:29 +01:00
@@ -110,39 +110,31 @@ class Restore: public default_backup::Re
namespace backup {
-class Snapshot_image: public Image_info
+class CS_snapshot: public Snapshot_info
{
public:
- Snapshot_image(Archive_info &info): Image_info(info)
- { ver= 1; }
+ CS_snapshot()
+ {
+ version= 1;
+ }
- image_type type() const
- { return SNAPSHOT_IMAGE; }
+ enum_snap_type type() const
+ { return CS_SNAPSHOT; }
const char* name() const
{ return "Snapshot"; }
bool accept(const Table_ref&, const ::handlerton* h)
- {
- return (h->start_consistent_snapshot != NULL);
+ {
+ return (h->start_consistent_snapshot != NULL);
}; // accept all tables that support consistent read
result_t get_backup_driver(Backup_driver* &ptr)
- { return (ptr= new snapshot_backup::Backup(tables,::current_thd)) ? OK : ERROR; }
+ { return (ptr= new snapshot_backup::Backup(m_tables,::current_thd)) ? OK : ERROR; }
result_t get_restore_driver(Restore_driver* &ptr)
- { return (ptr= new snapshot_backup::Restore(tables,::current_thd)) ? OK : ERROR; }
-
- result_t do_write_description(OStream&)
- { return OK; } // nothing to write
-
- static result_t
- create_from_stream(version_t, Archive_info &info, IStream&,
- Image_info* &ptr)
- {
- return (ptr= new Snapshot_image(info)) ? OK : ERROR;
- }
+ { return (ptr= new snapshot_backup::Restore(m_tables,::current_thd)) ? OK : ERROR; }
bool is_valid(){ return TRUE; };
diff -Nrup a/sql/backup/catalog.cc b/sql/backup/catalog.cc
--- a/sql/backup/catalog.cc 2007-11-29 20:34:06 +01:00
+++ b/sql/backup/catalog.cc 2007-11-30 09:23:29 +01:00
@@ -1,823 +1,239 @@
#include "../mysql_priv.h"
-/**
- @file
-
- Implementation of @c Archive_info and related classes.
- */
-
-/*
- TODO:
-
- - Add to Archive_info storage for other meta-data items.
- - Make existing storage solutions more rational (e.g., string pool).
- - Make reading code resistant to unknown image formats or meta-data types
- (or, assume it is handled by format version number).
- - Improve Image_info::Tables implementation (use some existing data structure).
- - Add more information to backup archive header , for example server's version
- string.
- - Handle backward compatibility (new code reads archive with earlier version
- number)
- - Add to Archive_info methods for browsing contents of the archive.
- */
-
-#if defined(USE_PRAGMA_IMPLEMENTATION) || defined(__APPLE_CC__)
-/*
- #pragma implementation is needed on powermac platform as otherwise compiler
- doesn't create/export vtable for Image_info::Tables class (if you know a
- better way for fixing this issue let me know! /Rafal).
-
- Apparently, configuration macro USE_PRAGMA_IMPLEMENTATION is not set by
- ./configure on powermac platform - this is why __APPLE_CC__ is also checked.
- */
-#pragma implementation
-#endif
-
-#include "backup_engine.h"
+#include <backup_stream.h>
#include "backup_aux.h"
#include "catalog.h"
-#include "be_default.h"
#include "be_snapshot.h"
+#include "be_default.h"
+#include "be_native.h"
+/**
+ @file
-/***************************************
-
- Implementation of Archive_info class
+ @brief Implements @c Image_info class and friends.
- ***************************************/
+ @todo Error reporting
+ @todo Store endianess info in the image.
+*/
namespace backup {
-Archive_info::~Archive_info()
-{
- for (uint i=0; i<256; ++i)
- if (images[i])
- {
- delete images[i];
- images[i]= NULL;
- }
-}
-
+/* Image_info implementation */
-/**
- Write header and catalogue of a backup archive.
-
- Header forms the first chunk of archive. Currently it contains archive's
- format version number followed by a list of table data images used in the
- archive.
-
- Next chunk contains the pool of database names. After that there is one chunk
- per image containing list of tables whose data is saved in that image.
- @verbatim
- =====================
- version number }
- --------------------- } header
- image descriptions }
- =====================
- db names }
- ===================== }
- tables of image 1 }
- ===================== }
- } catalogue
- ... }
- }
- ===================== }
- tables of image N }
- =====================
- @endverbatim
- In the picture "====" denotes chunk boundaries. Number of images is known
- from the header.
-
- The format in which image descriptions are saved is determined by
- @c Image_info::write_description() method.
-
- For list of databases and tables the format in which they are saved is
- defined by @c StringPool::save() and @c Archive_info::Tables::save() methods
- respectively.
- */
-
-result_t Archive_info::save(OStream &s)
+Image_info::Image_info():
+ table_count(0)
{
- DBUG_ENTER("Archive_info::save");
-
- size_t start_bytes= s.bytes;
- stream_result::value res;
-
- res= s.write2int(ver);
- if (res != stream_result::OK)
- {
- DBUG_PRINT("backup",("Can't write archive version number (stream_res=%d)",(int)res));
- DBUG_RETURN(ERROR);
- }
-
- // write list of images
- DBUG_PRINT("backup",(" writing image list"));
-
- uint ino;
- Image_info *img;
-
- for (ino=0; ino < img_count ; ++ino)
- if ((img= images[ino]))
- {
- DBUG_PRINT("backup",(" %2d: %s image",ino,img->name()));
- if (ERROR == img->write_description(s))
- {
- DBUG_PRINT("backup",("Can't write description of %s image (#%d)",
- img->name(),ino));
- DBUG_RETURN(ERROR);
- }
- }
-
- // close the header chunk
- res= s.end_chunk();
- if (res != stream_result::OK)
- {
- DBUG_PRINT("backup",("Error when closing image list chunk
(stream_res=%d)",(int)res));
- DBUG_RETURN(ERROR);
- }
-
+ /* initialize st_bstream_image_header members */
+ version= 1;
- // write catalogue
- DBUG_PRINT("backup",(" writing archive catalogue"));
-
- // db names (one chunk)
- if (ERROR == db_names.save(s)) // note: this closes the chunk
- {
- DBUG_PRINT("backup",("Error saving pool of db names (stream_res=%d)",(int)res));
- DBUG_RETURN(ERROR);
- }
+ /*
+ The arithmetic below assumes that MYSQL_VERSION_ID digits are arrenged
+ as follows: HLLRR where
+ H - major version number
+ L - minor version number
+ R - release
- // table lists (one chunk per image/list)
- for (ino=0; ino < img_count ; ++ino)
- if ((img= images[ino]))
- {
- DBUG_PRINT("backup",(" saving %s image's tables",img->name()));
- if (ERROR == img->tables.save(s))
- {
- DBUG_PRINT("backup",("Error saving tables (stream_res=%d)",(int)res));
- DBUG_RETURN(ERROR);
- }
- }
+ TODO: check if this is correct
+ */
+ DBUG_PRINT("backup",("version %d",MYSQL_VERSION_ID));
+ server_version.major= MYSQL_VERSION_ID / 10000;
+ server_version.minor= (MYSQL_VERSION_ID % 10000) / 100;
+ server_version.release= MYSQL_VERSION_ID % 100;
+ server_version.extra.begin= (byte*)MYSQL_SERVER_VERSION;
+ server_version.extra.end= server_version.extra.begin +
+ strlen((const char*)server_version.extra.begin);
- header_size= s.bytes - start_bytes;
+ flags= 0; // TODO: set BSTREAM_FLAG_BIG_ENDIAN flag accordingly
+ snap_count= 0;
- DBUG_RETURN(OK);
+ bzero(&start_time,sizeof(start_time));
+ bzero(&end_time,sizeof(end_time));
+ bzero(&vp_time,sizeof(vp_time));
+ bzero(&binlog_pos,sizeof(binlog_pos));
+ bzero(&binlog_group,sizeof(binlog_group));
+ bzero(m_snap, sizeof(m_snap));
}
-/**
- Fill @c Archive_info structure reading data from backup archive header and
- catalogue.
-
- @returns OK or ERROR
- */
-result_t Archive_info::read(IStream &s)
+Image_info::~Image_info()
{
- DBUG_ENTER("Archive_info::read");
-
- size_t start_bytes= s.bytes;
- result_t res;
- version_t ver;
-
- /*
- We read archive's header which starts with archive format version number.
- If we can't read the version number (end of stream or no data in the chunk)
- there is something wrong and we signal error.
- */
-
- stream_result::value rres= s.read2int(ver);
- if ( rres != stream_result::OK)
- {
- DBUG_PRINT("restore",("Error reading archive version number"
- " (stream_res=%d)",(int)rres));
- DBUG_RETURN(ERROR);
- }
-
- if (ver != Archive_info::ver)
- {
- DBUG_PRINT("restore",("Backup archive version %d not supported",ver));
- DBUG_RETURN(ERROR);
- }
-
- /*
- What follows (until the end of the data chunk) is a list of entries
- describing data images of the archive. It is read using
- Image_info::create_from_stream() function which returns DONE when end of
- chunk is reached.
- */
-
- DBUG_PRINT("restore",(" reading image list"));
-
- uint ino= 0;
-
- do
- {
- Image_info *img;
-
- res= Image_info::create_from_stream(*this,s,img);
-
- if (res == OK)
- {
- DBUG_ASSERT(img);
- DBUG_PRINT("restore",(" %2d: %s image",ino,img->name()));
- images[ino++]= img;
- }
-
- } while (res == OK && ino < MAX_IMAGES);
-
- img_count= ino;
+ // Delete snapshot objects
- // If res != DONE we haven't reached end of the chunk - something is wrong
- if (res != DONE)
+ for (uint no=0; no<256; ++no)
{
- DBUG_PRINT("restore",("Error when reading image list (%d images read)",
- img_count));
- DBUG_RETURN(ERROR);
- }
-
- /*
- Next chunk starts archive's catalogue. We proceed with reading it.
- Note that the catalogue should always contain at least one chunk (db names
- pool) and hence we should not hit end of stream here.
- */
-
- table_count= 0;
-
- if (s.next_chunk() != stream_result::OK)
- {
- DBUG_PRINT("restore",("Can't proceed to the catalogue"));
- DBUG_RETURN(ERROR);
+ if (m_snap[no])
+ delete m_snap[no];
+ m_snap[no]= NULL;
}
+}
- DBUG_PRINT("restore",(" reading catalogue (%d images)",img_count));
+/// Add table to database's table list.
+result_t Image_info::Db_item::add_table(Table_item &t)
+{
+ t.next_table= NULL;
+ t.base.db= this;
- /*
- First chunk of the catalogue contains db names pool - we read it and
- proceed to the next chunk. We should never hit end of stream here and
- so the only acceptable result of db.names.read() is OK.
- */
- res= db_names.read(s);
- if (res != OK)
+ if (!m_last_table)
{
- DBUG_PRINT("restore",("Can't read db names pool (res=%d)",(int)res));
- DBUG_RETURN(ERROR);
+ m_tables= m_last_table= &t;
}
-
- /*
- The following chunks contain lists of tables for each image. There are
- as many lists as there are images (possibly 0) and each list occupies
- one chunk.
- */
- for (uint ino=0; ino < img_count; ++ino)
+ else
{
- Image_info *img= images[ino];
-
- DBUG_PRINT("restore",(" reading %s image's tables (#%d)",img->name(),ino));
-
- /*
- There should be as many lists in the stream as there were images in the
- header. Thus we should never hit end of stream here.
- */
- res= img->tables.read(s); // note: proceeds to the next chunk in the stream
-
- if (res != OK)
- {
- DBUG_PRINT("restore",("Can't read table list for %s image (#%d)",
- img->name(),ino));
- DBUG_RETURN(ERROR); // neither stream nor chunk should end here
- }
-
- table_count+= img->tables.count();
-
- DBUG_PRINT("restore",(" finished reading tables"));
+ m_last_table->next_table= &t;
+ m_last_table= &t;
}
- header_size= s.bytes - start_bytes;
-
- DBUG_RETURN(OK);
-}
-
-} // backup namespace
-
-
-/**********************************
-
- Write/read image descriptions
-
- **********************************/
-
-namespace backup {
+ table_count++;
-/**
- Write entry describing (format of) a backup driver's image.
-
- Entry has the form:
- @verbatim
- | type | version | image description |
- @endverbatim
- where type is a byte holding Image_info::image_type value, version is 2 byte
- integer holding image format version. The format of optional image description
- is determined by @c X::do_write_description() method where X is a subclass of
- Image_info corresponding to given image type.
- */
-result_t
-Image_info::write_description(OStream &s)
-{
- // TODO: to handle unknown description formats, write description length here
-
- stream_result::value res= s.writebyte(type());
-
- if (res != stream_result::OK)
- return ERROR;
-
- res= s.write2int(ver);
-
- if (res != stream_result::OK)
- return ERROR;
-
- return do_write_description(s);
+ return OK;
}
/**
- Create @c Image_info instance from a saved entry describing it.
+ Locate in the catalogue an object described by the @c st_bstream_item_info
+ structure.
- @retval OK
- @retval DONE end of chunk/stream hit
- @retval ERROR
- */
-result_t
-Image_info::create_from_stream(Archive_info &info, IStream &s, Image_info*
&ptr)
+ @todo Handle unknown item types.
+*/
+Image_info::Item*
+Image_info::locate_item(const st_bstream_item_info *item) const
{
- uint ver;
- byte t;
-
- stream_result::value res= s.readbyte(t);
-
- // if we are at end of data chunk or stream, we should tell the caller
- if (res != stream_result::OK)
- return report_stream_result(res);
-
- res= s.read2int(ver);
-
- if (res != stream_result::OK)
- return ERROR;
-
- switch (image_type(t)) {
+ switch (item->type) {
- case NATIVE_IMAGE:
- return Native_image::create_from_stream(ver,info,s,ptr);
+ case BSTREAM_IT_DB:
+ return get_db(item->pos);
- case DEFAULT_IMAGE:
- return Default_image::create_from_stream(ver,info,s,ptr);
-
- case SNAPSHOT_IMAGE:
- return Snapshot_image::create_from_stream(ver,info,s,ptr);
+ case BSTREAM_IT_TABLE:
+ {
+ const st_bstream_table_info *ti= reinterpret_cast<const
st_bstream_table_info*>(item);
+ return get_table(ti->snap_no,item->pos);
+ }
default:
- DBUG_PRINT("restore",("Unknown image type %d",t));
- return ERROR;
+ // TODO: warn or report error
+ return NULL;
}
}
} // backup namespace
-/*******************
-
- Serialization of meta-data items
+/* catalogue services for backup stream library */
- *******************/
+extern "C" {
-namespace backup {
-
-/**
- Write an entry describing single meta-data item.
+/* iterators */
- Entry has format:
- @verbatim
- | type | id data | create data |
- @endverbatim
- Type is a single byte holding meta::Item::enum_type value. Id data is
- used to determine which item (from the archive catalogue) the entry
- corresponds to. Create data is used to create the item.
-
- The format of id data and create data for item of type X is determined
- by methods @c Archive_info::X_item::save_id() and @c meta::X::save(),
- respectively.
+static uint cset_iter; ///< Used to implement trivial charset iterator.
+static uint null_iter; ///< Used to implement trivial empty iterator.
- @see @c write_meta_data() for information about the format of the meta-data
- section of backup archive.
-*/
-result_t
-Archive_info::Item::save(THD *thd, OStream &s)
+void* bcat_iterator_get(st_bstream_image_header *catalogue, unsigned int type)
{
- byte b= meta().type();
-
- stream_result::value res=s.writebyte(b);
+ switch (type) {
- if (res != stream_result::OK)
- return ERROR;
+ case BSTREAM_IT_PERDB:
+ case BSTREAM_IT_PERTABLE:
+ return &null_iter;
- if (ERROR == save_id(s))
- return ERROR;
-
- return meta().save(thd,s);
-}
+ case BSTREAM_IT_CHARSET:
+ cset_iter= 0;
+ return &cset_iter;
-/**
- Create meta-data item from a saved entry.
-
- This function reads the type byte and calls @c create_from_stream method of
- corresponding class to create the item. It stores pointer to the created
- item in @c ptr argument.
-
- @retval OK if new item was created
- @retval DONE if end of chunk/stream was reached
- @retval ERROR if error has happened
- */
-result_t
-Archive_info::Item::create_from_stream(const Archive_info &info,
- IStream &s, Item* &ptr)
-{
- byte b;
+ case BSTREAM_IT_USER:
+ return &null_iter;
- stream_result::value res= s.readbyte(b);
+ case BSTREAM_IT_GLOBAL:
+ // only global items (for which meta-data is stored) are databases
+ case BSTREAM_IT_DB:
+ return
+ new
backup::Image_info::Db_iterator(*static_cast<backup::Image_info*>(catalogue));
+ // TODO: report error if iterator could not be created
- if (res != stream_result::OK)
- return report_stream_result(res);
-
- ptr= NULL;
-
- result_t res1;
-
- switch (meta::Item::enum_type(b)) {
-
- case meta::Item::DB:
- res1= Db_item::create_from_stream(info,s,ptr);
- break;
-
- case meta::Item::TABLE:
- res1= Table_item::create_from_stream(info,s,ptr);
- break;
-
- default: return ERROR;
+ default:
+ return NULL;
}
-
- /*
- Note that create_from_stream() should return OK - end of data should not
- happen here.
- */
- if (res1 != OK || ptr == NULL)
- return ERROR;
-
- return ptr->meta().read(s);
-}
-
-// Db items
-
-result_t Archive_info::Db_item::save_id(OStream &s)
-{
- uint k= key;
- DBUG_PRINT("backup",(" saving db-item (%d)",k));
- return stream_result::OK == s.writeint(k) ? OK : ERROR;
}
-result_t
-Archive_info::Db_item::create_from_stream(const Archive_info &i,
- IStream &s,
- Archive_info::Item* &ptr)
+struct st_bstream_item_info*
+bcat_iterator_next(st_bstream_image_header *catalogue, void *iter)
{
- uint k;
- stream_result::value res= s.readint(k);
-
- if (res != stream_result::OK)
- return report_stream_result(res);
-
- return (ptr= new Db_item(i,k)) ? OK : ERROR;
-}
-
-// Table items
-
-result_t Archive_info::Table_item::save_id(OStream &s)
-{
- DBUG_PRINT("backup",(" saving table-item (%d,%d)",img,pos));
- stream_result::value res= s.writeint(img);
-
- if (res != stream_result::OK)
- return ERROR;
-
- res= s.writeint(pos);
-
- if (res != stream_result::OK)
- return ERROR;
-
- return OK;
-}
-
-result_t
-Archive_info::Table_item::create_from_stream(const Archive_info &i,
- IStream &s,
- Archive_info::Item* &ptr)
-{
- uint img,no;
- stream_result::value res= s.readint(img);
-
- if (res != stream_result::OK)
- return report_stream_result(res);
+ /* If this is the null iterator, return NULL immediately */
+ if (iter == &null_iter)
+ return NULL;
- res= s.readint(no);
+ static bstream_blob name= {NULL, NULL};
- if (res != stream_result::OK)
- return ERROR;
-
- return (ptr= new Table_item(i,img,no)) ? OK : ERROR;
-}
-
-} // backup namespace
-
-
-/**********************************
-
- Implementation of Image_info::Tables
-
- **********************************/
-
-namespace backup {
-
-// TODO: use better implementation (red-black tree from mysys?)
-
-struct Image_info::Tables::node {
- StringPool::Key db;
- String name;
- node *next;
-
- node(const Image_info::Tables&,
- const StringPool::Key &k,
- const String &nm): db(k), next(NULL)
- {
- name.copy(nm);
- }
-};
-
-/// Empty the list.
-void Image_info::Tables::clear()
-{
- for (node *ptr= m_head; ptr;)
+ /*
+ If it is cset iterator then cset_iter variable contains iterator position.
+ We return only 2 charsets: the utf8 charset used to encode all strings and
+ the default server charset.
+ */
+ if (iter == &cset_iter)
{
- node *n=ptr;
- ptr= n->next;
- delete n;
- }
-
- m_head= m_last= NULL;
- m_count= 0;
-}
-
-/**
- Add a table to the list.
-
- @returns Position of the table or -1 if error
- */
-int Image_info::Tables::add(const backup::Table_ref &t)
-{
- StringPool::Key k= m_db_names.add(t.db().name());
-
- if (!k.is_valid())
- return -1;
-
- return add(k,t.name());
-}
-
-/// Add table at given position.
-int Image_info::Tables::add(const StringPool::Key &k, const String &name)
-{
- node *n= new node(*this,k,name);
+ switch (cset_iter) {
+ case 0: name.begin= (byte*)::my_charset_utf8_bin.csname; break;
+ case 1: name.begin= (byte*)::system_charset_info->csname; break;
+ default: name.begin= NULL; break;
+ }
- if (!n)
- return -1;
+ name.end= name.begin ? name.begin + strlen((char*)name.begin) : NULL;
+ cset_iter++;
- if (m_head == NULL)
- {
- m_count=1;
- m_head= m_last= n;
+ return name.begin ? (st_bstream_item_info*)&name : NULL;
}
- else
- {
- m_count++;
- m_last->next= n;
- m_last= n;
- };
-
- return m_count-1;
-}
-
-/**
- Locate table at given position.
- @returns Pointer to table's list node or NULL if position is not occupied
- */
-Image_info::Tables::node*
-Image_info::Tables::find_table(uint pos) const
-{
- DBUG_ASSERT(pos < m_count);
-
- node *ptr;
-
- for (ptr= m_head; ptr && pos; ptr= ptr->next)
- pos--;
-
- //if( !ptr ) ptr= m_last;
+ /*
+ In all other cases assume that iter points at instance of
+ @c Image_info::Iterator and use this instance to get next item.
+ */
+ const backup::Image_info::Item *ptr= (*(backup::Image_info::Iterator*)iter)++;
- return ptr;
+ return ptr ? (st_bstream_item_info*)(ptr->info()) : NULL;
}
-/// Return table at a given position.
-inline
-Table_ref Image_info::Tables::operator[](uint pos) const
+void bcat_iterator_free(st_bstream_image_header *catalogue, void *iter)
{
- // Get access to backup::Table_ref protected constructor
-
- struct Table_ref: public backup::Table_ref
- {
- Table_ref(const StringPool &db_names, Image_info::Tables::node &n):
- backup::Table_ref(db_names[n.db],n.name)
- {}
- };
+ /*
+ Do nothing for the null and cset iterators, but delete the
+ @c Image_info::Iterator object otherwise.
+ */
+ if (iter == &null_iter)
+ return;
- node *ptr= find_table(pos);
- DBUG_ASSERT(ptr);
+ if (iter == &cset_iter)
+ return;
- return Table_ref(m_db_names,*ptr);
+ delete (backup::Image_info::Iterator*)iter;
}
-/******************
-
- Serialization for Image_info::Tables class
-
- ******************/
+/* db-items iterator */
-/**
- Save list of tables in a backup stream.
-
- The format used assumes that a pool of database names is stored elsewhere.
- Thus for each table only the key of the database is stored as var-length
- integer followed by table name. Empty list is saved as single NIL value.
-
- The list is stored in a single stream chunk which determines its end.
-
- @returns OK or ERROR
- */
-result_t
-Image_info::Tables::save(OStream &s)
+void* bcat_db_iterator_get(st_bstream_image_header *catalogue, struct st_bstream_db_info
*db)
{
- DBUG_ENTER("Image_info::Tables::save");
- stream_result::value res;
+ using namespace backup;
- if (count() == 0)
- {
- res= s.writenil();
- if (res != stream_result::OK)
- DBUG_RETURN(ERROR);
- }
- else
- for (Tables::node *n= m_head ; n ; n= n->next)
- {
- res= s.writeint(n->db);
- if (res != stream_result::OK)
- DBUG_RETURN(ERROR);
-
- res= s.writestr(n->name);
- if (res != stream_result::OK)
- DBUG_RETURN(ERROR);
- };
+ Image_info::Db_item *dbi = static_cast<Image_info::Db_item*>(db);
- res= s.end_chunk();
- DBUG_RETURN(res == stream_result::ERROR ? ERROR : OK);
+ return
+ new Image_info::Ditem_iterator(*static_cast<backup::Image_info*>(catalogue),
+ *dbi);
}
-/**
- Read a list from a backup stream.
-
- @pre Stream is positioned at the first entry of the saved list.
- @post Stream is positioned at the beginning of next chunk or at its end.
-
- @retval OK
- @retval DONE end of stream or chunk hit (nothing has been read)
- @retval ERROR
- */
-result_t
-Image_info::Tables::read(IStream &s)
+struct st_bstream_dbitem_info*
+bcat_db_iterator_next(st_bstream_image_header *catalogue,
+ struct st_bstream_db_info *db,
+ void *iter)
{
- DBUG_ENTER("Image_info::Tables::read");
-
- stream_result::value res;
- uint k,tno=0;
-
- /*
- Read first entry - if it is NIL, we have empty list. Otherwise it should
- be db index of the first table.
- */
-
- res= s.readint(k);
-
- // If unexpected result, report an error or end of stream/chunk
- if (res != stream_result::OK && res != stream_result::NIL)
- DBUG_RETURN(report_stream_result(res));
-
- // empty the list
- clear();
-
- if (res == stream_result::OK) // this is non-empty list
- do
- {
- String name;
-
- res= s.readstr(name);
- if (res != stream_result::OK)
- break;
-
- tno= add(k,name);
- DBUG_PRINT("restore",("got next table %s.%s (pos %d, dbkey %d)",
- (*this)[tno].db().name().ptr(),
- (*this)[tno].name().ptr(),tno,k));
- res= s.readint(k);
- }
- while (res == stream_result::OK);
- else
- /*
- If we have read NIL value, pretend we are at the end of chunk so that
- no errors are reported below.
- */
- res= stream_result::EOC;
+ const backup::Image_info::Item *ptr= (*(backup::Image_info::Iterator*)iter)++;
- // we should be now at end of chunk/stream
- if (res != stream_result::EOC && res != stream_result::EOS)
- {
- DBUG_PRINT("restore",("Error when reading table no %d in table list",tno));
- DBUG_RETURN(ERROR);
- }
-
- res= s.next_chunk();
- DBUG_RETURN(res == stream_result::ERROR ? ERROR : OK);
+ return ptr ? (st_bstream_dbitem_info*)ptr->info() : NULL;
}
-} // backup namespace
-
-/**************************************
-
- Native image type definition
-
- **************************************/
-
-namespace backup {
-
-/*
- For native image its format (apart from the version number) is determined
- by the storage engine whose backup driver created it. Thus we save the name
- of storage engine.
-
- TODO: add more information here. E.g. the version number of the storage engine.
- */
-result_t
-Native_image::do_write_description(OStream &s)
+void bcat_db_iterator_free(st_bstream_image_header *catalogue,
+ struct st_bstream_db_info *db,
+ void *iter)
{
- String name(::ha_resolve_storage_engine_name(m_hton),&::my_charset_bin);
- return stream_result::OK == s.writestr(name) ? OK : ERROR;
+ delete (backup::Image_info::Ditem_iterator*)iter;
}
-result_t
-Native_image::create_from_stream(version_t ver,
- Archive_info &info,
- IStream &s, Image_info* &img)
-{
- String name;
- stream_result::value res= s.readstr(name);
-
- if (res != stream_result::OK)
- return report_stream_result(res);
-
- LEX_STRING name_lex= name;
-
-
- ::handlerton *hton= plugin_data(::ha_resolve_by_name(::current_thd,&name_lex),
- handlerton*);
- if (!hton)
- return ERROR;
-
- img= new Native_image(info,hton);
- if (!img)
- return ERROR;
-
- if (ver > img->ver)
- {
- DBUG_PRINT("restore",("Restore diver version %d can't read image version %d",
- img->ver,ver));
- return ERROR;
- }
-
- img->ver= ver;
-
- return OK;
}
-} // backup namespace
diff -Nrup a/sql/backup/catalog.h b/sql/backup/catalog.h
--- a/sql/backup/catalog.h 2007-11-29 20:34:06 +01:00
+++ b/sql/backup/catalog.h 2007-11-30 09:23:29 +01:00
@@ -1,500 +1,783 @@
-#ifndef _BACKUP_ARCHIVE_H
-#define _BACKUP_ARCHIVE_H
+#ifndef CATALOG_H_
+#define CATALOG_H_
+
+#include "stream_services.h"
+#include "stream.h"
+#include "backup_aux.h"
+#include <meta_data.h>
+
+namespace backup {
+
+class Snapshot_info;
/**
- @file
+ Describes contents of a backup image.
- Data types used to represent contents of a backup archive and to read/write
- its description (catalogue)
- */
+ This class stores a catalogue of a backup image, that is, description of
+ all items stored in it (currently only databases and tables).
-#if defined(USE_PRAGMA_INTERFACE) || defined(__APPLE_CC__)
-/*
- #pragma interface is needed on powermac platform as otherwise compiler
- doesn't create/export vtable for Image_info::Tables class (if you know a
- better way for fixing this issue let me know! /Rafal).
+ Only item names are stored in the catalogue. Other item data is stored
+ in the meta-data part of the image and in case of tables, their data is
+ stored in table data snapshots created by backup drivers.
- Apparently, configuration macro USE_PRAGMA_INTERFACE is not set by ./configure,
- on powermac platform - this is why __APPLE_CC__ is also checked.
+ For each snapshot present in the image there is a @c Snapshot_info object
+ stored in @c m_snap[] array. This object contains list of tables whose
+ data is stored in it. Note that each table must belong to exactly one
+ snapshot.
+
+ Contents of the catalogue can be browsed using the iterator classes.
+
+ Info about each object is stored in an instance of a class derived from
+ @c Image_info::Item. This class determines how to obtain meta-data for the
+ object and how to create it from the saved meta-data.
*/
-#pragma interface
-#endif
+class Image_info: public st_bstream_image_header
+{
+ public:
-#include <backup/api_types.h>
-#include <backup/string_pool.h>
-#include <backup/stream.h>
-#include <backup/backup_engine.h>
-#include <backup/meta_data.h>
+ uint table_count; ///< total number of tables in the archive
-namespace backup {
+ // Classes representing various types of meta-data items.
-// Forward declaration for a class describing an image inside backup archive.
-class Image_info;
+ class Item; ///< base class for all item types
+ class Db_item;
+ class Table_item;
-#define MAX_IMAGES 256
-typedef Image_info* Img_list[MAX_IMAGES]; ///< List (vector) of image descriptions.
+ class Iterator; ///< base for all iterators
+ class Db_iterator; ///< iterates over databases in archive
+ class Ditem_iterator; ///< iterates over per-db items
-/**
- Structure to hold information about binary log.
-*/
-struct st_binlog_info
-{
- char binlog_file_name[FN_REFLEN]; ///< the file name
- my_off_t position; ///< binlog position
-};
+ virtual ~Image_info();
-/**
- Describes contents of a backup archive.
+ protected:
- This class stores a catalogue of a backup archive, that is, description of
- all items stored in the archive (currently only databases and tables). It also
- determines how to save and read the catalogue to/from a backup stream.
+ class Db_ref;
+ class Table_ref;
- Only item names are stored in the catalogue. Other item data is stored
- in the meta-data part of an archive and in case of tables, their data is
- stored in images created by backup drivers.
+ /**
+ Provides storage for the list of databases stored in the catalogue.
+ */
+ class Databases
+ {
+ Dynamic_array<Db_item> m_dbs;
- The @c images member stores a list of @c Image_info objects describing the
- images included in the archive. Each image description contains a list of
- tables stored in that image (note that no table can be stored in more than
- one image).
-
- To save space, we have a separate pool of database names (@c db_names member).
- In table references, only the key of the database name is stored, not the
- whole name.
+ public:
+
+ Databases(): m_dbs(16,128)
+ {}
+
+ Db_item* operator[](uint pos) const
+ { return m_dbs[pos]; }
+
+ uint count() const
+ { return m_dbs.size(); }
+
+ /// Insert database at given location
+ Image_info::Db_item* add_db(const Db_ref &db, uint pos);
+
+ /// Insert database at first available position.
+ Image_info::Db_item* add_db(const Db_ref &db)
+ {
+ return add_db(db,count());
+ }
+
+ };
+
+ Databases m_db; ///< list of databases
+ Snapshot_info *m_snap[256]; ///< list of snapshots
+
+ Image_info();
- When reading or writing backup archive, statistics about the size of its parts
- is stored in the members of this class for later reporting.
- */
-class Archive_info
-{
public:
- static const version_t ver=1;
- uint img_count; ///< number of images in the archive
- uint table_count; ///< total number of tables in the archive
+ uint db_count() const
+ { return m_db.count(); }
- size_t total_size; ///< size of processed backup archive
- size_t header_size; ///< size of archive's header (after reading or writing an
archive)
- size_t meta_size; ///< size of archive's meta-data (after reading or writing an
archive)
- size_t data_size; ///< size of archive's table data images (after reading or
writing an archive)
-
- st_binlog_info binlog_information; ///< stores binlog information for PTR
- struct tm start_time; ///< the start datetime of the backup
- struct tm end_time; ///< the end datetime of the backup
- struct tm vp_time; ///< time of validation point
+ /*
+ Methods for populating backup catalogue (just wrappers which access m_db
+ member)
+ */
- // Classes representing various types of meta-data items.
+ Db_item* add_db(const Db_ref &db, uint pos)
+ {
+ return m_db.add_db(db,pos);
+ }
- class Item;
- class Db_item;
- class Table_item;
+ Db_item* add_db(const Db_ref &db)
+ {
+ return add_db(db,m_db.count());
+ }
+
+ Db_item* get_db(uint pos) const
+ {
+ return m_db[pos];
+ }
/*
- Classes which might be used to implement contents browsing.
+ Inline methods for adding/accessing table items are defined after
+ Snapshot_info class.
+ */
+
+ Table_item* add_table(Db_item&, const Table_ref&, uint, unsigned long int);
+ Table_item* add_table(Db_item&, const Table_ref&, uint);
+ Table_item* get_table(uint, unsigned long int) const;
- class Item_iterator; // for iterating over all meta-data items
- class Db_iterator; // iterates over databases in archive
- class Ditem_iterator; // iterates over per-db items
+ Item* locate_item(const st_bstream_item_info*) const;
+
+ private:
+
+ /**
+ Buffer for CREATE statement used in @c bcat_get_item_create_query()
+
+ FIXME: find a better solution.
*/
+ String create_stmt_buf;
- Img_list images; ///< list of archive's images
+ // friends
- /// Write archive's header and save the catalogue.
- result_t save(OStream&);
- /// Read the header and catalogue from a stream.
- result_t read(IStream&);
+ friend int ::bcat_add_item(st_bstream_image_header*, struct st_bstream_item_info*);
+ friend int ::bcat_reset(st_bstream_image_header*);
+ friend int ::bcat_get_item_create_query(st_bstream_image_header*,
+ struct st_bstream_item_info*,
+ bstream_blob *);
+};
- virtual ~Archive_info();
- protected:
+/*
+ Provides storage for list of tables of a snapshot.
- Archive_info():
- img_count(0), table_count(0),
- total_size(0), header_size(0), meta_size(0), data_size(0)
- {
- for (uint i=0; i<256; ++i)
- images[i]= NULL;
- }
+ Implements the Table_list interface.
+*/
- // storage for meta-data items
+class Tables: public Table_list
+{
+ Dynamic_array<Image_info::Table_item> m_tables;
- StringPool db_names; ///< Pool of database names.
+ public:
- private:
+ Tables(): m_tables(1024,1024)
+ {}
- friend class Image_info;
- friend class Db_item;
- friend class Table_item;
+ backup::Table_ref operator[](uint) const;
+
+ uint count() const
+ { return m_tables.size(); }
+
+ Image_info::Table_item* add_table(const Table_ref&, unsigned long int);
+
+ Image_info::Table_item* add_table(const Table_ref &t)
+ {
+ return add_table(t,count());
+ }
+
+ Image_info::Table_item* get_table(unsigned long int pos)
+ {
+ return m_tables[pos];
+ }
};
-/**
- Describes an image of table data stored in a backup archive.
- An instance of this class:
- - informs about the type of image,
- - stores list of tables whose data is kept in the image,
- - provides methods for creating backup and restore drivers to write/read the
- image,
- - determines which tables can be stored in the image,
- - defines how image's format is described inside backup archive
- (via @c do_write_description() method)
+/*
+ Describes table data snapshot stored inside backup image.
+
+ Such snapshot is created by a backup driver and read by a restore driver.
*/
-class Image_info
+class Snapshot_info
{
+ protected:
+
+ Tables m_tables; ///< list of tables whose data is stored in the snapshot
+
public:
- enum image_type {NATIVE_IMAGE, DEFAULT_IMAGE, SNAPSHOT_IMAGE};
+ enum enum_snap_type {
+ NATIVE_SNAPSHOT= BI_NATIVE, ///< snapshot created by native backup driver
+ DEFAULT_SNAPSHOT= BI_DEFAULT, ///< snapshot created by built-in, blocking driver
+ CS_SNAPSHOT= BI_CS ///< snapshot created by CS backup driver
+ };
- virtual image_type type() const =0; ///< Return type of the image.
- version_t ver; ///< Image format version.
+ version_t version; ///< version of snapshot's format
+
+ virtual enum_snap_type type() const =0;
/// Check if instance was correctly constructed
virtual bool is_valid() =0;
+
+ /// Tell how many tables are stored in the snapshot.
+ unsigned long int table_count() const
+ { return m_tables.count(); }
+
+ /// Determine if a table stored in given engine can be saved in this image.
+ virtual bool accept(const Table_ref&, const ::handlerton*) =0;
+
/// Create backup driver for the image.
virtual result_t get_backup_driver(Backup_driver*&) =0;
+
/// Create restore driver for the image.
virtual result_t get_restore_driver(Restore_driver*&) =0;
- size_t init_size; ///< Size of the initial data transfer (estimate). This is
- ///< meaningful only after a call to get_backup_driver().
-
- /// Write header entry describing the image.
- result_t write_description(OStream&);
+ /// Set snapshot's data format version
+ virtual result_t set_version(version_t ver)
+ {
+ version= ver;
+ return OK;
+ }
/**
- Create instance of @c Image_info described by an entry in backup stream.
+ Position inside image's snapshot list.
- @retval OK entry successfully read
- @retval DONE end of chunk or stream has been reached.
- @retval ERROR an error was detected
- */
- static result_t create_from_stream(Archive_info&, IStream&, Image_info*&);
+ Starts with 1. M_no == 0 means that this snapshot is n