Below is the list of changes that have just been committed into a local
5.1 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-04-13 12:02:26+02:00, rafal@quant.(none) +4 -0
WL#3327: Fix problem with restore from a backup archive which contains no table data.
Now archive can contain only the preamble (header+catalogs+metadata) and the restore
code correctly handles this situation.
sql/backup/backup_engine.h@stripped, 2007-04-13 12:02:20+02:00, rafal@quant.(none) +2 -2
Fix spelling typos.
sql/backup/meta_backup.cc@stripped, 2007-04-13 12:02:20+02:00, rafal@quant.(none) +1 -1
Allow empty table data in an archive (EOS directly after meta-data is OK).
sql/backup/stream.h@stripped, 2007-04-13 12:02:20+02:00, rafal@quant.(none) +162 -58
Add documentation for backup stream classes.
sql/backup/tables.cc@stripped, 2007-04-13 12:02:21+02:00, rafal@quant.(none) +2 -2
Fix error in table list reading code: list can be ended by EOS if it is stored at the
very end of a stream.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: rafal
# Host: quant.(none)
# Root: /ext/mysql/bk/backup/prototype
--- 1.3/sql/backup/backup_engine.h 2007-04-13 12:02:32 +02:00
+++ 1.4/sql/backup/backup_engine.h 2007-04-13 12:02:32 +02:00
@@ -538,7 +538,7 @@
Returning <code>OK</code> means that the data has been successfuly
processed
and the buffer can be re-used for further transfers. If method returns
- <code>PROCESSIG</code>, it means that the request was accepted but is not
completed yet. The buffer should
+ <code>PROCESSING</code>, it means that the request was accepted but is not
completed yet. The buffer should
not be used for other purposes until a further call to
<code>get_data()</code> with
the same buffer as argument returns <code>OK</code>. A
@@ -550,7 +550,7 @@
@retval DONE Same as OK but also indicates that the restore process is completed.
- @retval PROCESSIG The request was accepted but data is not processed yet -
+ @retval PROCESSING The request was accepted but data is not processed yet -
further calls to <code>send_data()</code> are needed to
complete it.
The buffer is blocked and can't be used for other transfers.
--- 1.11/sql/backup/meta_backup.cc 2007-04-13 12:02:32 +02:00
+++ 1.12/sql/backup/meta_backup.cc 2007-04-13 12:02:32 +02:00
@@ -269,7 +269,7 @@
DBUG_PRINT("restore",("catalog read"));
if( ino == 0 || res != stream_result::OK )
- DBUG_RETURN(res == stream_result::OK);
+ DBUG_RETURN( res == stream_result::OK || res == stream_result::EOS );
DBUG_RETURN(TRUE);
}
--- 1.7/sql/backup/stream.h 2007-04-13 12:02:32 +02:00
+++ 1.8/sql/backup/stream.h 2007-04-13 12:02:32 +02:00
@@ -358,6 +358,19 @@
};
};
+/**
+ Implementation of stream window interface to be used by util::{I,O}Stream
+ templates.
+
+ It provides a window inside a static data buffer <code>m_buf</code> of
+ fixed size <code>buf_size</code>. The window starts at
<code>m_head</code> and ends
+ at <code>m_end</code>. Window can be moved and resized using
<code>move()</code>
+ and <code>set_length()</code> methods. These methods take into account
+ size of <code>m_buf</code> and report overflows accordingly.
+
+ The window can be used by the util::{I,O}Stream templates to read/write
+ basic data types in a uniform, host independent way.
+ */
class Window
{
@@ -374,8 +387,8 @@
size_t length()
{ return m_end - m_head; }
- Result set_length(const size_t);
- Result move(const off_t);
+ Result set_length(const size_t); ///< resize window to the given size
+ Result move(const off_t); ///< move beginning of the window (shrinks size)
virtual ~Window() {}
@@ -388,14 +401,17 @@
static const size_t buf_size= 4*1024;
byte m_buf[buf_size];
- byte *last_byte;
- byte *m_head, *m_end;
+ byte *last_byte; ///< points at the byte after the last byte of m_buf
+ byte *m_head; ///< points at first byte of the current window
+ byte *m_end; ///< points at the byte after the last byte of the current window
bool m_blocked; ///< If true, set_length() and move() are blocked (return ERROR).
+ /// Create empty window at offset in m_buf
void reset(off_t offset=0)
{ m_head= m_end= m_buf+offset; }
+ /// Define the result which should be returned in case of buffer overflow.
virtual Result out_of_bounds() const
{ return stream_result::ERROR; }
@@ -443,72 +459,49 @@
};
-class IStream:
- Window,
- public Stream,
- public util::IStream< Window >
-{
- typedef util::IStream< Window > Base3;
+/**
+ Implement backup stream which writes data to a file.
- public:
+ This class inherits from util::OStream which defines methods for serialization of
+ basic datatypes (strings and integer). It also implements the concept of data chunks.
Data
+ is stored in chunks - writing to an IStream appends data to the current chunk. A chunk
is
+ closed and a new one is started with <code>end_chunk()</code> method.
- typedef stream_result::value Result; // disambiguate
+ A client of this class can ask an instance for an output buffer with
<code>get_window()</code>
+ method. After filling the buffer its contents can be written to the stream. This is to
avoid
+ double buffering and unneccessary copying of data. However, once an output buffer is
allocated,
+ all output to the stream is blocked until the buffer is written with
<code>write_window()</code>
+ or dropped with <code>drop_window()</code>.
+ */
- size_t bytes; ///< number of bytes read
+/*
+ Implementation of data chunks.
- bool open()
- {
- close(FALSE);
- return Stream::open() && rewind();
- }
+ Data is written to the file in form of data chunks. Each chunk is prefixed with its
size stored
+ in 2 bytes (should it be increased to 4?).
- void close(bool destroy=TRUE)
- {
- Stream::close();
- if (destroy)
- delete this;
- }
- bool rewind();
+ OStream instance uses an output buffer of fixed size inherited from Window class. The
size of
+ a chunk is limited by the size of this buffer as a whole chunk is stored inside the
buffer
+ before writting to the file.
- Result next_chunk();
+ Writting to the file happens when the current chunk is closed with
<code>end_chunk()</code>
+ method. At the time of writting the output, buffer contents is as follows:
- stream_result::value operator >>(String &str)
- {
- return readstr(str);
- }
+ ====================== <- m_buf
+ 2 bytes for chunk size
+ ====================== <- m_buf+2 (chunk data starts here)
- /**
- Return current chunk.
+ data written to
+ the chunk
- Will return the same chunk until next_chunk() is called.
- */
- stream_result::value operator >>(Buffer &buf)
- {
- m_end= last_byte;
+ ---------------------- <- m_head
- buf.data= m_buf;
- buf.size= last_byte - m_buf;
+ current output window
- return buf.size > 0 ? stream_result::OK : stream_result::EOS ;
- }
+ ====================== <- m_end (this is end of chunk data)
- IStream(const String &name):
- Stream(name,O_RDONLY),
- Base3(static_cast<Window&>(*this)),
- bytes(0)
- { last_byte= m_buf; }
-
- private:
-
- /// Length of next chunk of data or 0 if there are no more.
- uint next_chunk_len; // we use 2 bytes to store chunk len
-
- Result out_of_bounds() const
- { return next_chunk_len > 0 ? stream_result::EOC : stream_result::EOS; }
-
- friend class stream_instances;
-};
+ */
class OStream:
Window,
@@ -566,6 +559,117 @@
};
+
+/**
+ Implement backup stream reading data from a file.
+
+ This class inherits from util::IStream which defines methods for serialization of
+ basic datatypes (strings and integer). It also handles chunk boundaries as created by
+ the OStream class. When reading data at the end of a data chunk,
<code>stream_result::EOC</code>
+ is returned. To access data in next chunck, <code>next_chunk()</code> must
be called.
+ */
+
+/*
+ Handling of stream data chunks.
+
+ Chunks are read into the input buffer inherited from <code>Window</code>
class. It is assumed
+ that a whole chunk will always fit into the buffer (otherwise error is reported).
+
+ When reading a chunk of data, the size of the next chunk is also read-in in the same
file access
+ and stored in the <code>next_chunk_len</code> member.
+
+ The input buffer has the following layout:
+
+ =================== <- m_buf (start of input buffer)
+
+ chunk data
+
+ ------------------- <- m_head
+ current input
+ window
+ ------------------- <- m_end
+
+ chunk data
+
+ =================== <- last_byte (end of chunk data)
+ size of next chunk
+ =================== <- last_byte+2
+
+ The first chunk of data is read into the input buffer when stream is opened. Next
chunks are
+ read inside <code>next_chunk()</code> method.
+
+ */
+
+class IStream:
+ Window,
+ public Stream,
+ public util::IStream< Window >
+{
+ typedef util::IStream< Window > Base3;
+
+ public:
+
+ typedef stream_result::value Result; // disambiguate
+
+ size_t bytes; ///< number of bytes read
+
+ bool open()
+ {
+ close(FALSE);
+ return Stream::open() && rewind();
+ }
+
+ void close(bool destroy=TRUE)
+ {
+ Stream::close();
+ if (destroy)
+ delete this;
+ }
+
+ bool rewind();
+
+ Result next_chunk();
+
+ stream_result::value operator >>(String &str)
+ {
+ return readstr(str);
+ }
+
+ /**
+ Return current chunk.
+
+ Will return the same chunk until next_chunk() is called.
+ */
+ stream_result::value operator >>(Buffer &buf)
+ {
+ m_end= last_byte;
+
+ if (last_byte == m_buf) // empty chunk means end of stream
+ return stream_result::EOS;
+
+ buf.data= m_buf;
+ buf.size= last_byte - m_buf;
+
+ return stream_result::OK;
+ }
+
+ IStream(const String &name):
+ Stream(name,O_RDONLY),
+ Base3(static_cast<Window&>(*this)),
+ bytes(0)
+ { last_byte= m_buf; }
+
+ private:
+
+ /// Length of next chunk of data or 0 if there are no more.
+ uint next_chunk_len; // we use 2 bytes to store chunk len
+
+ Result out_of_bounds() const
+ { return next_chunk_len > 0 ? stream_result::EOC : stream_result::EOS; }
+
+ friend class stream_instances;
+};
+
// Function for debugging backup stream implementation.
void dump_stream(IStream &);
@@ -576,7 +680,7 @@
do { \
if ( (R) != stream_result::OK ) \
DBUG_PRINT(H,("stream op result= %d",(R))); \
- DBUG_ASSERT( (R) == stream_result::OK ); \
+ DBUG_ASSERT( (R) != stream_result::ERROR ); \
} while(0)
#define TEST_WR_RES(R) TEST_STR_RES("backup",(R))
#define TEST_RD_RES(R) TEST_STR_RES("restore",(R))
--- 1.2/sql/backup/tables.cc 2007-04-13 12:02:32 +02:00
+++ 1.3/sql/backup/tables.cc 2007-04-13 12:02:32 +02:00
@@ -113,9 +113,9 @@
tl[tno].name().ptr(),tno,k));
}
}
- while( res == stream_result::OK );
+ while (res == stream_result::OK);
- if( res == stream_result::EOC )
+ if (res == stream_result::EOC || res == stream_result::EOS)
res= str.next_chunk();
return res;
| Thread |
|---|
| • bk commit into 5.1 tree (rafal:1.2513) | rsomla | 13 Apr |