WL#4630: ST: MySQL Backup Client Program - Milestone 1
Affects: Server-6.0
—
Status: Complete
Milestone 1: * Display the metadata contained in the backup image (i.e, the SQL statements). * List objects contained in the backup image. * Display statistics about the backup image (e.g., compression algorithm, etc.). * Client should be a platform independent command-line utility where features are selected using options and parameters (e.g. mysqldump, mysql, etc.). * Search the backup image for data and display the object if found. Note: This may be limited to certain field and object types. * Search the backup image for a given object and display its metadata. * In case of problems with reading the image provide as much information as possible. E.g., the position of the failure.
The client program shall be called "mysqlbackup". For milestone 1 it shall have the following usage: Usage: mysqlbackup [options] backup-image-file -?, --help Display this help and exit. -#, --debug[=name] Output debug log. -V, --version Print version and exit. --catalog-summary Print summary from the database objects catalog. --catalog-details Print details from the database objects catalog. --metadata-statements Print SQL statements to create the database objects. --metadata-extra Print extra meta data for the database objects. --snapshots Print information about snapshots contained in the backup image. --data-chunks Print length of every data chunk contained in the backup image. --data-totals Print length of data contained in the backup image for each object. --summary Print summary information from end of the backup image. --all Print everything except snapshots and data-chunks. --exact Print exact number of bytes instead of human readable form. --search=name Search object in the backup image. Name can be object or database.object. Quoting of database and/or object with ", ', or ` is allowed. Wildcards % and _ are available. Use with --metadata-* options to see meta data. Plain name finds global objects, name1.name2 finds per db objects. The object types to be recognized by milestone 1 are: Character sets Users Tablespaces Databases Tables Views Stored procedures Stored functions Events Triggers Privileges Information that is not requested by options shall not be read from the image to save reading time. If seeking on the image is not possible, or the distance is not known, reading shall stop when no further information is requested. Times shall be printed in ISO format: YYYY-mm-dd HH:MM:SS Number shall be printed human readable by default. That is by using multipliers like KB, MB, GB, ... The output shall be well human readable. If possible it should also be parsable. The former has higher priority when in doubt. Sample output: ============== mysqlbackup --catalog-summary --catalog-details --data-totals --summary Image path: 'mysql-test/mysqlbackup-test.bak' Image size: 8458 KB Image compression: none Image version: 1 Creation time: 2008-11-16 11:51:40 UTC Server version: 6.0.9 (6.0.9-alpha) Server byte order: little-endian Server charset: 'utf8' Catalog summary: Databases: 3 Tables: 9 Other per db objects: 63 Catalog details: Tablespace 'mysqltest_ts1' Tablespace 'mysqltest_ts2' Database 'mysqltest1' Table 'mysqltest1'.'t1' Table 'mysqltest1'.'t2' Table 'mysqltest1'.'t3' Sproc 'mysqltest1'.'p1' Sproc 'mysqltest1'.'p2' Sfunc 'mysqltest1'.'f1' Sfunc 'mysqltest1'.'f2' View 'mysqltest1'.'v1' View 'mysqltest1'.'v2' Event 'mysqltest1'.'e1' Event 'mysqltest1'.'e2' Privilege 'mysqltest1'.''bup_user1'@'%' 00000008' Privilege 'mysqltest1'.''bup_user2'@'%' 00000009' Privilege 'mysqltest1'.''no_user'@'%' 00000010' Privilege 'mysqltest1'.''no_user'@'%' 00000011' Privilege 'mysqltest1'.''no_user'@'%' 00000012' Privilege 'mysqltest1'.''no_user'@'%' 00000013' Privilege 'mysqltest1'.''no_user'@'%' 00000014' Privilege 'mysqltest1'.''no_user'@'%' 00000015' Privilege 'mysqltest1'.''no_user'@'%' 00000016' Privilege 'mysqltest1'.''no_user'@'%' 00000017' Privilege 'mysqltest1'.''no_user'@'%' 00000018' Privilege 'mysqltest1'.''no_user'@'%' 00000019' Privilege 'mysqltest1'.''no_user'@'%' 00000020' Privilege 'mysqltest1'.''no_user'@'%' 00000021' Privilege 'mysqltest1'.''no_user'@'%' 00000022' Privilege 'mysqltest1'.''no_user'@'%' 00000023' Privilege 'mysqltest1'.''no_user'@'%' 00000024' Privilege 'mysqltest1'.''no_user'@'%' 00000025' Privilege 'mysqltest1'.''no_user'@'%' 00000026' Privilege 'mysqltest1'.''no_user'@'%' 00000027' Privilege 'mysqltest1'.''bup_user2'@'%' 00000028' Privilege 'mysqltest1'.''bup_user2'@'%' 00000029' Privilege 'mysqltest1'.''bup_user1'@'%' 00000030' Database 'mysqltest2' Table 'mysqltest2'.'t1' Table 'mysqltest2'.'t2' Table 'mysqltest2'.'t3' Sproc 'mysqltest2'.'p1' Sproc 'mysqltest2'.'p2' View 'mysqltest2'.'v1' View 'mysqltest2'.'v2' Event 'mysqltest2'.'e1' Event 'mysqltest2'.'e2' Trigger 'mysqltest2'.'r1' Trigger 'mysqltest2'.'r2' Privilege 'mysqltest2'.''bup_user1'@'%' 00000008' Privilege 'mysqltest2'.''bup_user1'@'%' 00000009' Privilege 'mysqltest2'.''bup_user1'@'%' 00000010' Privilege 'mysqltest2'.''bup_user1'@'%' 00000011' Privilege 'mysqltest2'.''bup_user1'@'%' 00000012' Privilege 'mysqltest2'.''bup_user1'@'%' 00000013' Privilege 'mysqltest2'.''bup_user1'@'%' 00000014' Privilege 'mysqltest2'.''bup_user1'@'%' 00000015' Privilege 'mysqltest2'.''bup_user1'@'%' 00000016' Privilege 'mysqltest2'.''bup_user1'@'%' 00000017' Privilege 'mysqltest2'.''bup_user1'@'%' 00000018' Privilege 'mysqltest2'.''bup_user1'@'%' 00000019' Privilege 'mysqltest2'.''bup_user1'@'%' 00000020' Privilege 'mysqltest2'.''bup_user1'@'%' 00000021' Privilege 'mysqltest2'.''bup_user1'@'%' 00000022' Privilege 'mysqltest2'.''bup_user1'@'%' 00000023' Privilege 'mysqltest2'.''bup_user1'@'%' 00000024' Privilege 'mysqltest2'.''bup_user1'@'%' 00000025' Database 'mysqltest3' Table 'mysqltest3'.'t1' Table 'mysqltest3'.'t2' Table 'mysqltest3'.'t3' Sfunc 'mysqltest3'.'f1' Sfunc 'mysqltest3'.'f2' View 'mysqltest3'.'v1' View 'mysqltest3'.'v2' Trigger 'mysqltest3'.'r1' Trigger 'mysqltest3'.'r2' Data totals: Backup has 939 KB for table 'mysqltest1'.'t1' Backup has 937 KB for table 'mysqltest1'.'t2' Backup has 937 KB for table 'mysqltest1'.'t3' Backup has 937 KB for table 'mysqltest2'.'t1' Backup has 937 KB for table 'mysqltest2'.'t2' Backup has 938 KB for table 'mysqltest2'.'t3' Backup has 937 KB for table 'mysqltest3'.'t1' Backup has 938 KB for table 'mysqltest3'.'t2' Backup has 937 KB for table 'mysqltest3'.'t3' Summary: Creation time: 2008-11-16 11:51:40 UTC Validity time: 2008-11-16 11:51:41 UTC Finish time: 1900-01-00 00:00:00 UTC No binlog information
mysqlbackup will consist of two modules: - The main program - The backup stream reader The main program will be written in C++: mysqlbackup.cc. Its tasks will be: - Initialize mysys components - Load default values from configuration files - Parse the command line - Drive the backup stream reader module - Provide an error message report function to the stream reader module - Search functionality - Print information retrieved from the stream, depending on the command line options - Free resources and return status The backup stream reader will be written in C: backup_stream.c. Its tasks will be: - Drive the backup stream library - Provide call-back function for the stream library (see below) - Build an item catalog from the items received by the call-backs - Provide a convenient interface for the main program (see below) The structure of the catalog and the functions to drive its build are specified in backup_stream.h: /* Catalog. The dynamic arrays hold pointers to items of the following types: struct st_backup_charset cat_charsets struct st_backup_database cat_databases struct st_backup_snapshot cat_snapshots note: cat_header must be first element in st_backup_catalog. */ struct st_backup_catalog { struct st_bstream_image_header cat_header; /* must be 1st */ const char *cat_zalgo; const char *cat_image_path; my_off_t cat_image_size; DYNAMIC_ARRAY cat_charsets; DYNAMIC_ARRAY cat_databases; DYNAMIC_ARRAY cat_snapshots; }; /* Meta data. */ struct st_backup_metadata { struct st_blob md_query; struct st_blob md_data; }; /* Character set. note: cs_item must be first element in st_backup_charset. */ struct st_backup_charset { struct st_bstream_item_info cs_item; /* must be 1st */ }; /* Per database objects, e.g. views. note: perdb_item must be first element in st_backup_table. */ struct st_backup_perdb { struct st_bstream_dbitem_info perdb_item; /* must be 1st */ struct st_backup_metadata perdb_metadata; }; /* Table. note: tbl_item must be first element in st_backup_table. */ struct st_backup_table { struct st_bstream_table_info tbl_item; /* must be 1st */ struct st_backup_metadata tbl_metadata; ulonglong tbl_data_size; }; /* Database. The dynamic array holds pointers to items of the following type: struct st_backup_table db_tables struct st_backup_perdb db_perdbs note: db_item must be first element in st_backup_database. */ struct st_backup_database { struct st_bstream_db_info db_item; /* must be 1st */ struct st_backup_metadata db_metadata; DYNAMIC_ARRAY db_tables; DYNAMIC_ARRAY db_perdbs; }; /* Snapshot. Tables belong to databases. But in the table data chunks they are numbered by snapshot number and table number. The table number is relative to the snapshot. To find the table item within its database we need an index from the table number (pos) within the snapshot to the table item. For every snapshot there is a struct st_backup_snapshot with an array that has a reference per table of that snapshot. The dynamic array holds pointers to items of the following type: struct st_backup_table snap_index_pos_to_table */ struct st_backup_snapshot { DYNAMIC_ARRAY snap_index_pos_to_table; }; In the dynamic arrays, we store pointers to catalog items only. Some items reference others. These pointers would become invalid when the array is reallocated on insert of a new element. Each item is allocated before its pointer is inserted in an array. Before deleting the array, all elements must be freed. The simplified work flow as used by the mysqlbackup client looks like so: backup_catalog_allocate() // initialize catalog backup_image_open() // open image and read header backup_read_catalog() // read and build catalog backup_read_metadata() // read meta data and add to catalog do { backup_read_snapshot() // read a table data chunk } while more table data follows backup_read_summary() // read summary section backup_image_close() // close image backup_catalog_free() // free all catalog resources The steps backup_read_catalog() until backup_read_summary() can be skipped, when the user does not request information from it. But if information from any later section is required, all former needs to to be read too. Call-backs for the stream library that must be implemented for reading backup streams: /** Allocate given amount of memory and return pointer to it. @param[in] size amount of memory to allocate @return pointer to allocated memory */ bstream_byte* bstream_alloc(unsigned long int size); /** Free previously allocated memory. @param[in] ptr pointer to allocated memory */ void bstream_free(bstream_byte *ptr); /** Read from the stream/image. @param[in,out] strm stream handle, updating position @param[in,out] data data container, updating contents and ptrs @param envelope not used @return status @retval BSTREAM_OK ok @retval BSTREAM_EOS end of stream @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. */ static int str_read(struct st_stream *strm, struct st_blob *data, struct st_blob envelope __attribute__((unused))); /** Skip part of the stream/image. @param[in,out] strm stream handle, updating position @param[in,out] len number of bytes to skip, skipped @return status @retval BSTREAM_OK ok @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. */ static int str_forward(struct st_stream *strm, size_t *len); /** Clear catalogue and prepare it for populating with items. @param[in] hdr catalog reference @return status @retval BSTREAM_OK ok @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. @note This is empty because backup_catalog_allocate() initializes the catalog properly. */ int bcat_reset(struct st_bstream_image_header *hdr __attribute__((unused))); /** Close catalogue after all items have been added to it. This allows for finalizing operations. It is not meant for deletion of the catalog. There is no "open" action. The approximate counterpart to bcat_close() is bcat_reset(). @param[in] hdr catalog reference @return status @retval BSTREAM_OK ok @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. @note This is empty because there is no finalization required. */ int bcat_close(struct st_bstream_image_header *hdr __attribute__((unused))); /** Add item to the catalog. For items that belong to a database, the base.db element points to the databases' catalog item. The stream library evaluates that pointer using an iterator provided by bcat_iterator_get(). The item name is allocated by the stream library and must be freed by the application later. @param[in,out] hdr catalog ref, updating catalog @param[in] item item reference @return status @retval BSTREAM_OK ok @retval otherwise error @note item->pos should be set to indicate position of the item in the catalogue. This is a global position per item type. Items that belong to a database are not numbered relative to the database. @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. @note Global, per-table and per-database items can have independent address spaces. Thus item belonging to a database is identified by its position inside that database's item list. Similar for items belonging to tables. */ int bcat_add_item(struct st_bstream_image_header *hdr, struct st_bstream_item_info *item); /** Create global iterator of a given type. Possible iterator types. - BSTREAM_IT_CHARSET: all charsets - BSTREAM_IT_USER: all users - BSTREAM_IT_DB: all databases The following types of iterators iterate only over items for which some meta-data should be saved in the image. - BSTREAM_IT_GLOBAL: all global items in create-dependency order - BSTREAM_IT_PERDB: all per-db items except tables which are enumerated by a table iterator (see below) - BSTREAM_IT_PERTABLE: all per-table items in create-dependency orders. @param[in] hdr catalog reference @param[in] it_type iterator type @return pointer to the iterator @retval NULL error */ void* bcat_iterator_get(struct st_bstream_image_header *hdr, unsigned int it_type); /** Return next item pointed by iterator. @param[in] hdr catalog reference @param[in] iter_arg iterator reference @return pointer to catalog item @retval NULL error */ struct st_bstream_item_info* bcat_iterator_next(struct st_bstream_image_header *hdr __attribute__((unused)), void *iter_arg); /** Free iterator resources. @param[in] hdr catalog reference @param[in] iter_arg iterator reference @note The iterator can not be used after call to this function. */ void bcat_iterator_free(struct st_bstream_image_header *hdr __attribute__((unused)), void *iter_arg); /** Create database object from its meta-data. When the meta-data section of backup image is read, items can be created as their meta-data is read (so that there is no need to store these meta-data). This functions stores them in the catalog instead of creating database objects. So the application can make different use of the data. @param[in] hdr catalog reference @param[in] item item reference @param[in] query query string @param[in] data data blob @note The item has set the 'type' element only. No item name nor a catalog position is provided. Let alone a reference to a database. @note Either query or data or both can be empty, depending on what was stored in the image. @note The blob provided by query and/or data is not guaranteed to exist after the call. It must be copied to become part of the catalog. @return status @retval BSTREAM_OK ok @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. */ int bcat_create_item(struct st_bstream_image_header *hdr, struct st_bstream_item_info *item, struct st_blob query, struct st_blob data); ======== The following call-back functions must be present for linkage, but will be empty: /** Create iterator for items belonging to a given database. @param[in] hdr catalog reference @param[in] db database item reference @return pointer to the iterator @retval NULL error @note Not used when reading a backup stream. */ void* bcat_db_iterator_get(struct st_bstream_image_header *hdr __attribute__((unused)), struct st_bstream_db_info *db __attribute__((unused))); /** Return next item from database items iterator @param[in] hdr catalog reference @param[in] db database item reference @param[in] iter_arg iterator reference @return pointer to catalog item @retval NULL error @note Not used when reading a backup stream. */ struct st_bstream_dbitem_info* bcat_db_iterator_next(struct st_bstream_image_header *hdr __attribute__((unused)), struct st_bstream_db_info *db __attribute__((unused)), void *iter_arg __attribute__((unused))); /** Free database items iterator resources @param[in] hdr catalog reference @param[in] db database item reference @param[in] iter_arg iterator reference @note Not used when reading a backup stream. */ void bcat_db_iterator_free(struct st_bstream_image_header *hdr __attribute__((unused)), struct st_bstream_db_info *db __attribute__((unused)), void *iter_arg __attribute__((unused))); /** Produce CREATE statement for a given item. Backup stream library calls this function when saving item's meta-data. If function successfully produces the statement, it becomes part of meta-data. @param[in] hdr catalog reference @param[in] item item reference @param[out] query query string @return status @retval BSTREAM_OK ok @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. @note Not used when reading a backup stream. */ int bcat_get_item_create_query(struct st_bstream_image_header *hdr __attribute__((unused)), struct st_bstream_item_info *item __attribute__((unused)), bstream_blob *query __attribute__((unused))); /** Return meta-data (other than CREATE statement) for a given item. Backup stream library calls this function when saving item's meta-data. If function returns successfully, the bytes returned become part of meta-data. @param[in] hdr catalog reference @param[in] item item reference @param[out] data data blob @return status @retval BSTREAM_OK ok @retval otherwise error @note The return value is specified as 'int' in stream_v1.h though only values from enum_bstream_ret_codes are expected. @note Not used when reading a backup stream. */ int bcat_get_item_create_data(struct st_bstream_image_header *hdr __attribute__((unused)), struct st_bstream_item_info *item __attribute__((unused)), struct st_blob *data __attribute__((unused))); ======== The program will have a catalog reader module, that hides the stream library details with its call-back functions from the application. It will provide the following functions: /** Allocate a backup catalog. @return catalog reference @retval NULL error */ struct st_backup_catalog* backup_catalog_allocate(void); /** Free a backup catalog. @param[in] bup_catalog catalog reference */ void backup_catalog_free(struct st_backup_catalog *bup_catalog); /** Open a backup image. @param[in] filename file name @param[in] bup_catalog catalog reference @return image handle reference @retval NULL error */ void* backup_image_open(const char *filename, struct st_backup_catalog *bup_catalog); /** Close a backup image. @param[in] image_handle image handle reference */ void backup_image_close(void* image_handle); /** Read backup image catalog. @param[in] image_handle image handle reference @param[in] bup_catalog catalog reference @return status @retval BSTREAM_OK ok @retval != BSTREAM_OK error */ enum enum_bstream_ret_codes backup_read_catalog(void* image_handle, struct st_backup_catalog *bup_catalog); /** Read backup image meta data. @param[in] image_handle image handle reference @param[in] bup_catalog catalog reference @return status @retval BSTREAM_OK ok @retval != BSTREAM_OK error */ enum enum_bstream_ret_codes backup_read_metadata(void *image_handle, struct st_backup_catalog *bup_catalog); /** Read backup image table data. @param[in] image_handle image handle reference @param[in] bup_catalog catalog reference @return status @retval BSTREAM_OK ok @retval != BSTREAM_OK error */ enum enum_bstream_ret_codes backup_read_snapshot(void *image_handle, struct st_backup_catalog *bup_catalog __attribute__((unused)), struct st_bstream_data_chunk *snapshot); /** Read backup image summary. @param[in] image_handle image handle reference @param[in] bup_catalog catalog reference @return status @retval BSTREAM_OK ok @retval != BSTREAM_OK error */ enum enum_bstream_ret_codes backup_read_summary(void* image_handle, struct st_backup_catalog *bup_catalog); /** Locate a database object by catalog coordinates. Catalog coordinates for databases are: pos database position in catalog @param[in] bup_catalog catalog reference @param[in] pos position in catalog's database array @return database reference */ struct st_backup_database* backup_locate_database(struct st_backup_catalog *bup_catalog, uint pos); /** Locate a table object by catalog coordinates. Catalog coordinates for tables are: snap_num snapshot position in catalog pos table position in snapshot @param[in] bup_catalog catalog reference @param[in] snap_num position in catalog's snapshot array @param[in] pos position in snapshot's table index array @return table reference */ struct st_backup_table* backup_locate_table(struct st_backup_catalog *bup_catalog, uint snap_num, uint pos); /** Locate a perdb object by catalog coordinates. Catalog coordinates for perdb items are: db_pos database position in catalog pos perdb item position in database @param[in] bup_catalog catalog reference @param[in] db_pos position in catalog's database array @param[in] pos position in database's perdb array @return perdb item reference */ struct st_backup_perdb* backup_locate_perdb(struct st_backup_catalog *bup_catalog, uint db_pos, uint pos);
Copyright (c) 2000, 2024, Oracle Corporation and/or its affiliates. All rights reserved.