<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5313622847232042654</id><updated>2011-12-13T07:45:52.563-08:00</updated><category term='PBMS MySQL PBXT BLOBS'/><category term='PHP'/><category term='PBMS'/><category term='PBXT'/><category term='MySQL'/><category term='S3'/><category term='OPenSQL'/><category term='Drizzle'/><category term='Cloud'/><category term='Replication'/><category term='InnoDB'/><category term='BLOBS'/><title type='text'>Barry's PrimeBase Development</title><subtitle type='html'>Notes and comments relating to my source code development for the PrimeBase open source projects for MySQL, Drizzle, the PrimeBase XT engine (PBXT) and the PrimeBase BLOB Streaming daemon (PBMS).</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-1751625083051908108</id><published>2011-05-26T09:12:00.000-07:00</published><updated>2011-05-26T09:12:53.412-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><title type='text'>What is in the PBMS patch for MySQL 5.5</title><content type='html'>I thought people may be interested to know what the PBMS patch for MySQL actually patches, in case they should think this is a major hack into the MySQL source code.&lt;br /&gt;&lt;br /&gt;Almost all of&amp;nbsp; the patch consists of&amp;nbsp; the PBMS daemon source code which is added to the "storage/pbms" folder in the MySQL source code tree. Other than that here is a list of the actual MySQL files touched and what the patch is for:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;sql/CMakeLists.txt&lt;/b&gt;: &lt;br /&gt;Added PBMS source directories to the header file search list. &lt;br /&gt;Lines added: 1.&lt;/li&gt;&lt;li&gt;&lt;b&gt;sql/handler.cc&lt;/b&gt;: &lt;br /&gt;Added PBMS server side API calls to check for longblob columns being modified or tables containing longblob columns being dropped or renamed. This is the guts of the PBMS patch. &lt;br /&gt;Lines added: 170.&lt;/li&gt;&lt;li&gt;&lt;b&gt;libmysql/CMakeLists.txt&lt;/b&gt;:&lt;br /&gt;Added PBMS API functions to the client API functions list and the PBMS source directories to the header file search list.&amp;nbsp; Also adds the PBMS lib source code to the MySQL client lib build.&lt;br /&gt;Lines added: 61.&lt;/li&gt;&lt;li&gt;&lt;b&gt;include/mysql.h&lt;/b&gt;: &lt;br /&gt;Added a line to include the PBMS&amp;nbsp; LIB header file "pbmslib.h". &lt;br /&gt;Lines added: 3.&lt;/li&gt;&lt;li&gt;&lt;b&gt;include/mysql.h.pp&lt;/b&gt;: &lt;br /&gt;Added lines to reflect the changes made to the MySQL client API when adding the PBMS API to it: &lt;br /&gt;Lines added: 42.&lt;/li&gt;&lt;li&gt;&lt;b&gt;include/pbmslib.h&lt;/b&gt;: &lt;br /&gt;Added a new file that redirects to the actual pbmslib.h which is in "storage/pbms/lib". This was added in order to simplify the build process. When installed it is the actual pbmslib.h from "storage/pbms/lib" that is installed.&lt;/li&gt;&lt;li&gt;&lt;b&gt;client/CMakeLists.txt&lt;/b&gt;: &lt;br /&gt;Added PBMS source directories to the header file search list. &lt;br /&gt;Lines added: 1.&lt;/li&gt;&lt;li&gt;&lt;b&gt;client/mysqldump.c&lt;/b&gt;: &lt;br /&gt;Added code to recognize PBMS BLOB URLs and fetch the BLOB data and write it out to a separate file. &lt;br /&gt;Lines added: 176.&lt;/li&gt;&lt;li&gt;&lt;b&gt;client/mysql.cc&lt;/b&gt;: &lt;br /&gt;Added code to be able to upload the BLOB dump file from mysqldump to the PBMS daemon. &lt;br /&gt;Lines added: 92&lt;/li&gt;&lt;/ul&gt;As you can see the actual changes to the MySQL code itself if fairly limited and safe. The patched MySQL server and applications can still be used without PBMS with out any negative effect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-1751625083051908108?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/1751625083051908108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=1751625083051908108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/1751625083051908108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/1751625083051908108'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/05/what-is-in-pbms-patch-for-mysql-55.html' title='What is in the PBMS patch for MySQL 5.5'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-6519630638390697071</id><published>2011-05-25T15:15:00.000-07:00</published><updated>2011-05-25T15:15:01.875-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Replication'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='S3'/><category scheme='http://www.blogger.com/atom/ns#' term='Cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>PBMS Version 2 released</title><content type='html'>Version 2 of the PBMS daemon is now ready.&lt;br /&gt;&lt;br /&gt;Here are the major changes introduced with this version:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;b&gt;PBMS is fully integrated with MySQL 5.5:&lt;/b&gt;&lt;br /&gt;PBMS is now provided as a patch for MySQL 5.5 which simplifies installation and provides numerous benefits.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;All engines are "PBMS enabled":&lt;/b&gt; &lt;br /&gt;PBMS no longer requires that you have a "PBMS enabled" storage engine to be able to use PBMS.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;The MySQL client lib provides the PBMS client API:&lt;/b&gt; &lt;br /&gt;You no longer need to link your application to a separate PBMS lib to use the PBMS 'C' API.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;mysqldump understands PBMS BLOB URLS:&lt;/b&gt; &lt;br /&gt;When dumping tables or databases containing PBMS BLOB URLs mysqldump will dump the referenced BLOBs as binary data to a separate file. Since the BLOBs are dumped to their own file there is no need to convert them to hex data so they consumes only half the disk space they would have otherwise. The dump process is faster and uses less memory because the BLOBs are streamed directly from the PBMS daemon into the file.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;The mysql client handles the PBMS BLOB dump file:&lt;/b&gt; &lt;br /&gt;When restoring a database or table from a dump, the file into which the BLOB data was dumped can be passed as a command-line argument. The mysql client will then stream the BLOB data directly to the PBMS daemon which is faster and requires far less memory than if it where sent back to the server via 'insert' statements. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;A PBMS daemon ID is part of the BLOB URL:&lt;/b&gt; &lt;br /&gt;Each PBMS daemon has its own unique ID number. This allows the PBMS daemon to recognize and handle inserts of PBMS BLOB URLs from other PBMS daemons. A PBMS system table is provided into which daemon information can be inserted for other remote PBMS daemons.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;BLOB replication is handled automatically:&lt;/b&gt; &lt;br /&gt;When a PBMS BLOB URL is inserted int a table on a slave server the PBMS daemon recognizes that the URL comes from another PBMS daemon and so it sends a request to the original daemon and pulls the BLOB across so that it is now replicated locally.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;New internal BLOB indexing system:&lt;/b&gt; &lt;br /&gt;A new PBMS BLOB indexing system improves BLOB access performance and BLOB tracking.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;PBMS system tables are now indexed:&lt;/b&gt; &lt;br /&gt;The PBMS system tables that provide access to BLOB metadata are now indexed so that accessing the tables no longer automatically results in a table scan of the entire BLOB repository.&lt;/li&gt;&lt;/ul&gt;This is a major version change and as a result is not backward  compatible with the earlier versions of PBMS. If you have an older  installation that you need to upgrade please contact me and I will give  you details on how best to do this.&lt;br /&gt;&lt;br /&gt;The documentation and web page for PBMS has also been updated so I invite to check it out at: &lt;a href="http://www.blobstreaming.org/"&gt;http://www.blobstreaming.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You may notice a change in the documentation with regards to the definition of PBMS. The abbreviation 'PBMS' is being kept but what it stands for is being changed.&amp;nbsp; Originally it stood for "PrimeBase Media Streaming" but it occurred to me that when a DBA is designing a database system they are not likely to ask them selves the question "How will I stream my media?" but they may well ask them selves "How will I manage my BLOBs?".&amp;nbsp; So PBMS now stands for "&lt;b&gt;P&lt;/b&gt;rimeBase &lt;b&gt;B&lt;/b&gt;LOB &lt;b&gt;M&lt;/b&gt;anagement &lt;b&gt;S&lt;/b&gt;ystem" which I think is a little more intuitive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-6519630638390697071?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/6519630638390697071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=6519630638390697071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6519630638390697071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6519630638390697071'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/05/pbms-version-2-released.html' title='PBMS Version 2 released'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-5440997975385571626</id><published>2011-04-20T08:26:00.000-07:00</published><updated>2011-04-20T08:26:21.773-07:00</updated><title type='text'>MySQL 5.1 Plugin Development</title><content type='html'>I just wanted to compliment Sergei Golubchik and Andrew Hutchings on their book "MySQL 5.1 Plugin Development". This is a must have for anyone starting out or in the process of writing plugins for MySQL. It provides a lot of detail that is missing in other books or if you are just trying to figure things out by looking at what other plugins do.&lt;br /&gt;&lt;br /&gt;This is the first place I have ever seen the table and index flags explained along with information on what the MySQL server will do with this information.&lt;br /&gt;&lt;br /&gt;Well done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-5440997975385571626?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/5440997975385571626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=5440997975385571626' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5440997975385571626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5440997975385571626'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/04/mysql-51-plugin-development.html' title='MySQL 5.1 Plugin Development'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-6069956336316922498</id><published>2011-04-13T07:33:00.000-07:00</published><updated>2011-04-13T07:33:30.853-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>PBMS presentation at MySQL Conference</title><content type='html'>Just a reminder that I will be presenting a session on PBMS at the &lt;br /&gt;MySQL Conference on Thursday April 14 at 10:50.&lt;br /&gt;&lt;br /&gt;The title is "&lt;span style="font-size: small;"&gt;BLOB Data And Thinking Out Side The Box" where I will be talking about the new PBMS daemon with a focus on how it handles replication and backup.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;Hope to see you there!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-6069956336316922498?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/6069956336316922498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=6069956336316922498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6069956336316922498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6069956336316922498'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/04/pbms-presentation-at-mysql-conference.html' title='PBMS presentation at MySQL Conference'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-418692305001422397</id><published>2011-04-05T07:11:00.000-07:00</published><updated>2011-04-05T07:11:40.229-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='InnoDB'/><title type='text'>Why use PBMS?</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;span style="font-size: 16pt;"&gt;&lt;b&gt;Why use PBMS?&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;I have talked to people about why they should use PBMS to handle BLOB data often enough, so I was surprised when someone asked me where they could find this information and I discovered I had never actually written it down anywhere.&lt;span&gt;&amp;nbsp; &lt;/span&gt;So here it is.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;style&gt;@font-face {  font-family: "Times New Roman";}p.MsoNormal, li.MsoNormal, div.MsoNormal { margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: "Times New Roman"; }a:link, span.MsoHyperlink { color: blue; text-decoration: underline; }a:visited, span.MsoHyperlinkFollowed { color: purple; text-decoration: underline; }table.MsoNormalTable { font-size: 10pt; font-family: "Times New Roman"; }div.Section1 { page: Section1; }&lt;/style&gt;    &lt;/div&gt;&lt;div class="MsoNormal"&gt;If you are unfamiliar with PBMS, PBMS stands for PrimeBase Media Streaming. For details please have a look at the home page for &lt;a href="http://www.blobstreaming.org/"&gt;BLOB Streaming&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&amp;nbsp;  &lt;div class="MsoNormal"&gt;Both MySQL and Drizzle are not designed to handle BLOB data efficiently. This is not a storage engine problem, most storage engines can store BLOB data reasonably efficiently, but the problem is in the server architecture itself. The problem is that the BLOB data is transferred to and from the server as part of the regular result set. To do this both the server and the client must allocate a buffer large enough to hold the entire BLOB. DBMSs that are designed to handle BLOBs such as Oracle, SyBase, and PrimeBase all pass the BLOB data outside of the regular result set. This way they avoid the requirement of having to buffer the entire BLOB. APIs such as ODBC understand this and provide functions such as SQLGetData() that can be called multiple times to retrieve data in chunks so that the client doesn’t need to buffer BLOBs if it doesn’t need to.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;PBMS is designed to address this problem and provide MySQL and Drizzle with a means to efficiently handle BLOB data by allowing BLOB data to be transferred outside of the regular result set.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;There are currently 2 approaches to handling BLOBs when using MySQL or Drizzle, one approach is to just store the BLOB data in the database in a Blob column which I will call the “BLOBs in database” approach, the other is to store the BLOB in a file some where and then store the path to the file in the database, which I will call the “BLOBs in files” approach.&amp;nbsp; I will compare these 2 methods of handling BLOB data to the "PBMS" approach which is to use the PBMS daemon.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;The BLOBs in database approach:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Advantages:&lt;/b&gt;&lt;/div&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal"&gt;Simple      to implement, BLOB data is treated no different than any other data.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Flexible,      DBMS independent applications can be written using ODBC or JDBC to access      the data. &lt;/li&gt;&lt;li class="MsoNormal"&gt;The      referential integrity of the BLOB data is ensured by the database. &lt;/li&gt;&lt;li class="MsoNormal"&gt;Standard      database maintenance ensures the security of the data. &lt;/li&gt;&lt;/ul&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Disadvantages:&lt;/b&gt;&lt;/div&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal"&gt;The      BLOB data is buffered on both the server and client side so that a 100 M      BLOB will require a 100 M buffer on the server and then another on the      client to receive the BLOB into.&lt;span&gt;&amp;nbsp;      &lt;/span&gt;If the server is busy handling 100 such requests then it will need      10 G of buffer space.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Database      replication becomes impractical because of the size of the logs when the      BLOB data is written to them.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      use of mysqldump, or similar tools to backup databases result in huge      backup files because the BLOBs must be converted to hex strings in order      to write then to the backup log which doubles their size.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      MySQL cluster server cannot be used with databases containing BLOBs.&lt;/li&gt;&lt;/ul&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;&lt;u&gt;The BLOBs in files approach:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Advantages:&lt;/b&gt;&lt;/div&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal"&gt;The      BLOB data is not part of the result set so large buffers are not required.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      BLOB data can be store in a location that is remote from the database      server.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Standard      replication will work (but the BLOB data will not be replicated).&lt;/li&gt;&lt;li class="MsoNormal"&gt;Standard      backup procedures can be used with the database (but the BLOB data will      not be backed up).&lt;/li&gt;&lt;/ul&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Disadvantages:&lt;/b&gt;&lt;/div&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal"&gt;A      separate backup solution must be found for the BLOB data while keeping it      consistent with the database backups.&lt;/li&gt;&lt;li class="MsoNormal"&gt;A      separate solution is required to replicate BLOB data. &lt;/li&gt;&lt;li class="MsoNormal"&gt;Requires      a custom designed system including client software.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      client software needs to know how the BLOBs are stored and needs to be      provided with a method of accessing the BLOBs. If the BLOBs are not      located locally to the client then additional software may be required.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      referential integrity, making sure that the BLOB files being stored on the      file system are consistent with the BLOB references stored in the      database, is no longer controlled by the database server.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Doesn’t      scale well because most file system perform poorly when the number of      files starts to exceed a couple of million.&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal"&gt;Installation      and maintenance is more complex because specialized knowledge is required.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The client application is responsible for handling&amp;nbsp; the effects of transaction rollbacks in ensuring referential integrity.&lt;/li&gt;&lt;/ul&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;&lt;u&gt;The PBMS approach:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Advantages:&lt;/b&gt;&lt;/div&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal"&gt;Simple      to implement, all data storage and access is handled by the database      server and PBMS engine.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Flexible,      DBMS independent applications can be written using JDBC to access the      data. &lt;/li&gt;&lt;li class="MsoNormal"&gt;The      referential integrity of the BLOB data is ensured by the database. &lt;/li&gt;&lt;li class="MsoNormal"&gt;Standard      database maintenance ensures the security of the data. No special      knowledge is required.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Replication      of the BLOB data is possible.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      BLOB data can be streamed in and out of the database so that buffer sizes      are independent of the size of the BLOBs.&lt;/li&gt;&lt;li class="MsoNormal"&gt;Better      performance, test show that inserts and selects are significantly faster      when BLOBs of 50 K or more are handled using PBMS.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      solution scales well, BLOBs are packed into files so the number of files      in the file system is much less than you would get with a one BLOB per      file system. &lt;/li&gt;&lt;li class="MsoNormal"&gt;The      maximum size of a BLOB is only limited by the maximum file size of the      host machine.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      BLOB data can be stored in a location remote from the database server,      such as on a different machine or in S3 cloud storage. This reduces the      load on the database server host and it’s network bandwidth use.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The PBMS daemon ensures that BLOB inserts and deletes are handled properly in the event of a transaction rollback. Transaction check points are also supported.&lt;/li&gt;&lt;/ul&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b&gt;Disadvantages:&lt;/b&gt;&lt;/div&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal"&gt;PBMS      is not shipped with any MySQL distribution, but it is ship with Drizzle      and can be downloaded from http://www.blobstreaming.org.&lt;/li&gt;&lt;li class="MsoNormal"&gt;The      MySQL server does not directly support PBMS but Drizzle does provides      direct support.&lt;/li&gt;&lt;/ul&gt;&lt;div class="MsoNormal" style="margin-left: 0.25in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Although MySQL doesn’t support PBMS directly it is not difficult to add support to the InnoDB engine and anyone interested can contact me and I will happily assist them with it. I use InnoDB for most of my testing.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="font-size: 14pt;"&gt;&lt;b&gt;&lt;u&gt;Conclusions:&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;PBMS provides efficient BLOB handling that is missing from MySQL and Drizzle. This would be enhanced greatly by integrating PBMS support more directly into the MySQL server. &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;I currently have plans to increase the support for PBMS in drizzle by adding a new column type for storing PBMS BLOB references. This enables the use of PBMS to be part of the database schema design and simplifies support for client libraries. The client library will then be able to recognize it is getting a BLOB reference and can then make calls to the PBMS daemon to stream the data back to the client. Ideally this is the type of support MySQL should also provide PBMS.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-418692305001422397?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/418692305001422397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=418692305001422397' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/418692305001422397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/418692305001422397'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/04/why-use-pbms.html' title='Why use PBMS?'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-1523141048096148922</id><published>2011-03-23T18:01:00.000-07:00</published><updated>2011-03-23T18:02:23.438-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Replication'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>New PBMS version</title><content type='html'>&lt;span class="branch-url" style="font-size: small;"&gt;A new version of PBMS for drizzle has been pushed up to launchpad:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://code.launchpad.net/%7Ebarry-leslie/drizzle/drizzle_pbmsV2"&gt;&lt;span class="branch-url" style="font-size: small;"&gt;drizzle_pbmsV2&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="branch-url"&gt;I have rewritten PBMS and changed the way that BLOBs are referenced in order to make PBMS more flexible and to fix some of it's limitations. I have also removed some of the more confusing parts of the code and reorganized it in an attempt to make it easier for people to find there way around it.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="branch-url" style="font-size: large;"&gt;So apart form some cosmetic changes what is different?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="branch-url"&gt;Maybe the best answer would be to say what hasn't changed: the user and engine API&amp;nbsp; and the way in which the actual data is stored on the disk remains pretty much unchanged, but everything else has changed.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="branch-url"&gt;&lt;span style="font-size: small;"&gt;The best place&lt;/span&gt; to start is with the BLOB URL, the old URL looked like this:&lt;/span&gt;&lt;br /&gt;&lt;div style="color: blue;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;"~*1261157929~5-128-6147b252-0-0-37"&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt;the new URL looks like this:&lt;/span&gt;&lt;br /&gt;&lt;div style="color: blue;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;"pbmsAdaVAQCAAAAAAAAAANaVAQCAAAAAAAAAAG30qzsGAAAAAAAAAAEAAACAAAAAAAAAAAEAAAAAAAAA"&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt;which is obviously a lot more intuitive.&amp;nbsp; :)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;OK maybe it is bigger and uglier but it contains a lot more information. It is actually a base64 URL encoding of a data&amp;nbsp; structure containing information about the BLOB that makes it universally locatable across different PBMS daemons running locally or remotely.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;How is this done?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;When a BLOB is uploaded to a PBMS daemon the URL generated for it contains, among other things, the PBMS daemon's server id as well as the database ID and the BLOB's repository index value. These 3 values remain with the BLOB for it's life regardless of what server or database it may eventually end up in.&amp;nbsp; This allows you to insert a BLOB URL from one database into another database, possibly on a different server, and the PBMS engine will be able to use the URL to look up the blob, if it cannot find it in the database's repository then PBMS will automatically fetch the BLOB from the source server or database.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When fetching the BLOB the current server id, database id and index, which are also stored in the URL, are used.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;This means that the following will work:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;insert into foo.blob_table1 select * from&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: small;"&gt;bar.ablob_table;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;insert into foo.blob_table2 select * from&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: small;"&gt;bar.ablob_table;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;The first insert will copy the BLOBs from the BLOB repository for database 'bar' into the repository for database 'foo'.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;The second insert will will recognize that the BLOBs already exists in foo's BLOB repository and just add references to them.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;The same would hold true if database 'foo' was on a different server on the other side of the world.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;BLOBs and replication:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;A practical use for this is with replication, the replication process replicates the BLOB URLS to the slave server and PBMS pulls the BLOB across automatically. You can try this out using drizzle replication and my &lt;/span&gt;&lt;span class="branch-url"&gt;&lt;a href="https://code.launchpad.net/%7Ebarry-leslie/drizzle/drizzle_pbmsV2"&gt;drizzle_pbmsV2&lt;/a&gt; branch.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="branch-url"&gt;The only thing you need to do is tell the slave server how to map the PBMS server ID to the actual server. You do that by inserting the information into the 'pbms_server' table in the slave machine's pbms database. The master server's PBMS server ID can be found by doing the following select on the master server:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="branch-url"&gt;select * from pbms.pbms_server;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="branch-url"&gt;Resulting in something like this: &lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="branch-url"&gt;+-------+-----------+------+--------------+&lt;br /&gt;| Id&amp;nbsp;&amp;nbsp;&amp;nbsp; | Address&amp;nbsp;&amp;nbsp; | Port | Description&amp;nbsp; |&lt;br /&gt;+-------+-----------+------+--------------+&lt;br /&gt;| 38358 | localhost | 8080 | This server. | &lt;br /&gt;+-------+-----------+------+--------------+&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Then on the slave server do the following insert:&lt;br /&gt;&lt;blockquote&gt;&amp;nbsp;insert into &lt;span class="branch-url"&gt;pbms.pbms_server values(38358, "master_host", 8080, "The master replication server");&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="branch-url"&gt;where &lt;/span&gt;&lt;span class="branch-url"&gt;"master_host" will be the same IP address as you have for "master-host" in the drizzle slave config file.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="branch-url"&gt;&lt;b&gt;Note:&lt;/b&gt; The PBMS server ID is not the same as the drizzle server id.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;What else:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With the new design of the PBMS daemon it would not be very difficult to create a stand alone BLOB repository server that could be used as a backup for BLOBs or a a central repository for a cluster of servers.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;The next step though is to update the PBMS documentation and build a version&amp;nbsp; for MySQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-1523141048096148922?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/1523141048096148922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=1523141048096148922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/1523141048096148922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/1523141048096148922'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/03/new-pbms-version.html' title='New PBMS version'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-3438518773858330619</id><published>2011-03-11T13:58:00.000-08:00</published><updated>2011-03-11T13:58:59.291-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='InnoDB'/><title type='text'>PBMS Performance</title><content type='html'>I have been doing some performance testing with PBMS and found a few things that were kind of interesting. The main finding was that you start to see performance improvements when data sizes start to reach the 20K level. This was seen when replacing a 20 K varchar field with a longblob column in a PBMS enabled table.&lt;br /&gt;&lt;br /&gt;The following graph shows the performance differences for 'select' and 'insert' statements using a PBMS enabled version of InnoDB on an 8 core machine.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-HBM_CyB1aBA/TXqIPKKq5EI/AAAAAAAAAC4/SjY_jHtsqfY/s1600/PBMS_performance.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="391" src="https://lh5.googleusercontent.com/-HBM_CyB1aBA/TXqIPKKq5EI/AAAAAAAAAC4/SjY_jHtsqfY/s400/PBMS_performance.jpg" width="400" /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The test compares the insert and select performance of LongBlob columns with PBMS support against that of varchar and longtext columns when using InnoDB.&lt;/div&gt;&lt;br /&gt;The test shows that depending on if your application is more heavily weighted towards Inserts or selects it may be beneficial to replace columns containing more than 10K of data with longblob columns with PBMS support. In all cases the performance of both 'selects' and 'inserts' was improved for columns containing more than 20K when using longblob columns and PBMS. As the data size in the column increased the performance gain by using PBMS also increased, at 10 M there was %580 performance improvement for selects.&lt;br /&gt;&lt;br /&gt;The testing showed some performance irregularities with PBMS which when fixed should result in even better performance. &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;If anyone would like to try this themselves please contact me and I can give you a copy of the test tool I used as well as a PBMS enabled version of InnoDB.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Barry&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-3438518773858330619?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/3438518773858330619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=3438518773858330619' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/3438518773858330619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/3438518773858330619'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2011/03/pbms-performance.html' title='PBMS Performance'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-HBM_CyB1aBA/TXqIPKKq5EI/AAAAAAAAAC4/SjY_jHtsqfY/s72-c/PBMS_performance.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-5252529482396931830</id><published>2010-07-22T14:47:00.000-07:00</published><updated>2010-07-22T15:12:52.377-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>PBMS version 0.5.015 beta has been released.</title><content type='html'>A new release of the PrimeBase Media Streaming daemon is now available for download at&lt;br /&gt;&lt;a href="http://www.blobstreaming.org/"&gt;http://www.blobstreaming.org&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;This release doesn't contain any major new features just some bug fixes and a lot of house keeping changes.&lt;br /&gt;&lt;br /&gt;If you look at the download section on &lt;a href="http://www.blobstreaming.org/"&gt;http://www.blobstreaming.org&lt;/a&gt; you will see that there are now more packages that can be downloaded. I have separated out different client side components from the PBMS project and created separate launchPad projects for each one.  You can see them listed in the "Related Links" side panel to the right of this post.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The "&lt;span style="font-weight: bold;"&gt;PBMS Client Library&lt;/span&gt;"  facilitates communication with the PBMS daemon.   This library is independent of the PBMS daemon's host server and can be used to communicate with a   PBMS daemon hosted by the MySQL or Drizzle database servers.&lt;/li&gt;&lt;li&gt;The "&lt;span style="font-weight: bold;"&gt;PBMS PHP extension&lt;/span&gt;" is a PHP module that enables PHP to connect directly to the PBMS engine   and stream BLOB data in and out of a MySQL or Drizzle database.   &lt;/li&gt;&lt;li&gt;The "&lt;span style="font-size:100%;"&gt;&lt;strong&gt;Streaming enabled JDBC Driver" &lt;/strong&gt;&lt;/span&gt; is a streaming enable version of the standard MySQL Connector/J, JDBC Driver. &lt;/li&gt;&lt;/ul&gt;One minor new feature that was added is that the PBMS HTTP server how understands the HTTP "range" header that can be used to request a section of BLOB data. The Client Library and PHP extension have both been updated with &lt;span class="pbms-api-func-name"&gt;pbms_get_data_range() functions.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-5252529482396931830?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/5252529482396931830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=5252529482396931830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5252529482396931830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5252529482396931830'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2010/07/pbms-version-05015-beta-has-been.html' title='PBMS version 0.5.015 beta has been released.'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-5933636087855764469</id><published>2010-07-08T09:49:00.000-07:00</published><updated>2010-07-08T15:58:31.120-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>PBMS is in the Drizzle tree!</title><content type='html'>If you haven't already heard PBMS is now part of the Drizzle tree.&lt;br /&gt;&lt;br /&gt;Getting it there was a fair bit of work but not as much as I had thought it would be. The process of getting it to work with Drizzle and running it thorough Hudson has improved the code a lot. It is amazing what some compilers will catch that others will let by. I am now a firm believer in treating all compiler warnings as errors.&lt;br /&gt;&lt;br /&gt;I am just in the process of updating the PBMS plugin so that it will build and install the PBMS client library (libpbmscl.so) as well as the plugin.  The PBMS client library is a standalone library that can be used to access the PBMS daemon weather it is running as part of MySQL or Drizzle. So a PBMS client library built with Drizzle can be used to access a PBMS daemon running as part of MySQL and vice-versa.&lt;br /&gt;&lt;br /&gt;There is also PHP extension for PBMS that is basically just a wrapper for the library. Currently this is part of the PBMS project on launchpad but I am working on getting it into pecl. The PHP extension has a set of test cases with it which is what I use to test PBMS with.&lt;br /&gt;&lt;br /&gt;If anybody is interested in taking on the task of creating a python module for PBMS I would be happy to provide what ever help you may need. I think it would just be a wrapper around the  PBMS client library almost identical to the PHP extension. I would recoment just taking the  PHP extension and converting it.&lt;br /&gt;&lt;br /&gt;Now that I have PBMS in Drizzle I am planning on getting replication working with PBMS. I have decided that the best way to do this is to do a bit of work rearranging how PBMS uses the BLOB URLs to reference the BLOB data. The URLs already contain a server, database, and table id so the plan is to change things so that PBMS can handle BLOB URLS from other servers being inserted or referenced. Once this is working then I will automatically have replication and 95% of what is needed to support clustered servers.&lt;br /&gt;&lt;br /&gt;I will go into detail on this in a later posting which will include pretty pictures.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-5933636087855764469?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/5933636087855764469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=5933636087855764469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5933636087855764469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5933636087855764469'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2010/07/pbms-is-in-drizzle-tree.html' title='PBMS is in the Drizzle tree!'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-7867495126397656169</id><published>2010-04-27T10:19:00.000-07:00</published><updated>2010-04-27T10:51:42.391-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>BLOBs are not just blobs</title><content type='html'>Recently when talking to someone about PBMS it occurred to me that I had been thinking about BLOBs in the traditional database sense in that they were atomic blocks of data the content of which the server knew nothing about. But with PBMS that need not be the case.&lt;br /&gt;&lt;br /&gt;The simplest enhancement would be to allow the client to send a BLOB request to the PBMS daemon with an offset and size to just return a chunk of the BLOB. Depending on the application and the BLOB contents this may make perfectly good sense, why force the client to retrieve the entire BLOB if it only want part of it.&lt;br /&gt;&lt;br /&gt;A much more interesting idea would be to enable the user to provide custom server side functions that they could run against the BLOB.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;So how would his work?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The PBMS daemon would provide its own "BLOB functions" plugin API. The API would be quite simple where the plugin would register the function names it supports. When the PBMS daemon receives a BLOB request specifying a BLOB function name, it calls the BLOB function passing it a hook to the BLOB data and then returns to the client what ever the function returns.&lt;br /&gt;&lt;br /&gt;The first use of this that I can imagine would be to provide a function that would return the thumbnail from a jpeg image rather than the entire image. Other functions may just return the jpeg metadata.&lt;br /&gt;&lt;br /&gt;The idea is that BLOBs are not just blobs but are highly structured documents which, given the knowledge of the document structure,  it is possible to return portions of the BLOB that are of interest to particular applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-7867495126397656169?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/7867495126397656169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=7867495126397656169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/7867495126397656169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/7867495126397656169'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2010/04/blobs-are-not-just-blobs.html' title='BLOBs are not just blobs'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2598140999869023252</id><published>2010-03-05T13:03:00.000-08:00</published><updated>2010-03-05T13:10:03.622-08:00</updated><title type='text'>PBMS daemon performance update.</title><content type='html'>I have updated the PBMS download to 0.5.12-beta.&lt;br /&gt;&lt;br /&gt;When doing some performance testing I found a severe bug that effectively limited the upload of files to 1 file every 2 seconds regardless of file size. :( Now that I have fixed this it is possible to upload 1000+ BLOB per second depending on size.&lt;br /&gt;&lt;br /&gt;I believe this bug has been in there for the last couple of versions. So if you had tried PBMS and thought it slow please try it again.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This version also includes a performance test tool called pbms_performance. I plan on posting some performance data soon.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2598140999869023252?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2598140999869023252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2598140999869023252' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2598140999869023252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2598140999869023252'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2010/03/pbms-daemon-performance-update.html' title='PBMS daemon performance update.'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2388353600488196226</id><published>2010-02-26T14:57:00.000-08:00</published><updated>2010-02-26T16:27:51.846-08:00</updated><title type='text'>PBMS version 0.5.011 beta has been released.</title><content type='html'>A new release of the PrimeBase Media Streaming daemon is now available for download at&lt;br /&gt;&lt;a href="http://www.blobstreaming.org/"&gt;http://www.blobstreaming.org&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;This release has been focused on getting S3 storage back into PBMS.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's new:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    The PBMS daemon now provides two storage methods for BLOB data: local storage and S3 storage. Using S3 storage, repository records are kept for each BLOB the same as in local storage but the actual BLOB data is stored remotely on an S3 server. &lt;a href="http://bpbdev.blogspot.com/2009/11/pbms-cloud-storage-is-back.html"&gt;Click here&lt;/a&gt; to see my earlier posting on S3 storage.&lt;/li&gt;&lt;li&gt;    When using S3 storage the PBMS daemon holds the public/private keys but the actual transfer of BLOB data, both upload and download, is done directly between the client application and the S3 server.&lt;/li&gt;&lt;li&gt;    Backup and recovery have been modified to work with S3 storage so that BLOBs stored on S3 servers are backed up on the S3 server. To find out more about this &lt;a href="http://bpbdev.blogspot.com/2009/11/pbms-backup-and-s3-storage.html"&gt;click here&lt;/a&gt; to go to a previous BLOG entry on this subject.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The PBMS enabled MySQL java connector has been updated and is now working again.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;    The PrimeBase Media Streaming web site has been updated and the documentation has been made more user friendly.&lt;/li&gt;&lt;li&gt;A new system table was added to the 'pbms' database called 'pbms_enabled' that lists the pbms enabled engines currently loaded by the MySQL server.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;As you may have noticed there has been a bit of a name change in that I now refer to the &lt;span style="font-style: italic;"&gt;PBMS daemon&lt;/span&gt; as apposed to the &lt;span style="font-style: italic;"&gt;PBMS engine&lt;/span&gt;. Refferring to PBMS as a storage engine was a bit confusing because  its main purpose is to act as an independent daemon that handles the transfer of BLOB data to and from clients.  The fact that it  publishes itself internally in the MySQL server as a storage engine, supports the storage engine interface, and takes part in transactions is all part of the implementation details and is not part of its core purpose.&lt;br /&gt;&lt;br /&gt;Speaking of core purposes: The BLOB alias feature has been removed. This feature let the user assign an alias to a BLOB that could then later be used in place of the BLOB URL generated by PBMS to access the BLOB. It was decided that this feature was not part of the PBMS daemon's core purpose and since supporting it in a transactional manner would have added considerable complexity to the PBMS daemon it was dropped.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;What's  next:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I &lt;span style="font-weight: bold;"&gt;really&lt;/span&gt; want to get this working with drizzle.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run some performance tests comparing BLOB handling performance on MySQL with and with out the PBMS daemon and its impact on the over all performance of the MySQL server.&lt;/li&gt;&lt;li&gt;The performance with S3 is not as good as it should be, the cause of this needs to be found and fixed.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2388353600488196226?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2388353600488196226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2388353600488196226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2388353600488196226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2388353600488196226'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2010/02/pbms-version-05011-beta-has-been.html' title='PBMS version 0.5.011 beta has been released.'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-383176410971588446</id><published>2009-11-06T07:30:00.000-08:00</published><updated>2009-11-06T14:14:59.657-08:00</updated><title type='text'>PBMS backup and S3 storage</title><content type='html'>Hi,&lt;br /&gt;&lt;br /&gt;So I had to make some changes to the way that backup worked with PBMS in order that it would behave as expected when the BLOB data is stored remotely on an S3 server.&lt;br /&gt;&lt;br /&gt;I will go over how the PBMS repository is backed up first and then explain how it works with S3 storage.&lt;br /&gt;&lt;br /&gt;PBMS provides a pbms_backup table in its 'pbms' database that records all the backups that have been performed on any of the PBMS repositories on the server. The create statement for this table looks like this:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;CREATE TABLE &lt;span style="font-weight: bold;"&gt;pbms.pbms_backup&lt;/span&gt; (&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;id&lt;/span&gt;                INT NOT NULL AUTO_INCREMENT,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Database_Name&lt;/span&gt;     VARCHAR(64) NOT NULL,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Started &lt;/span&gt;                     TIMESTAMP,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Completed&lt;/span&gt;                TIMESTAMP,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IsRunning&lt;/span&gt;                 BOOL,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IsDump&lt;/span&gt;                     BOOL,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Location&lt;/span&gt;                    VARCHAR(1024),&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cloud_Ref &lt;/span&gt;               INT,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cloud_backup_no&lt;/span&gt;  INT,&lt;br /&gt;PRIMARY KEY (id)&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;There are 2 ways to backup a PBMS repository:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;MySQLDump&lt;/span&gt;: To backup the repository using 'mysqldump' you simply dump the database's 'pbms_dump' table. This table is a one column table of type 'long blob'. Any select from this table is assumed to be a repository backup and any insert into the table is assumed to be a repository recovery.  Selecting the data from the 'pbms_dump' table results in a new record being added to the 'pbms.pbms_backup' table. To recover the repository the dumped data is inserted back into the 'pbms_dump' table. During the recovery it is important to set the pbms variable "Restoring-Dump" in the database's 'pbms_variable' table to "TRUE". This tells the PBMS engine that the database is being recovered and that insertion of BLOB references should not increment the BLOB reference count.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Engine level backup&lt;/span&gt;: To perform an engine level backup all you do is insert a record into the 'pbms.pbms_backup' table providing the name of the database to be backed up and the location into which the backup should be placed. This starts an asynchronous backup operation. To recover the repository from the backup all you do is drag and drop the backup into your recovered database.&lt;/li&gt;&lt;/ul&gt;So how does this work when the actual BLOB data is stored on an S3 server?&lt;br /&gt;&lt;br /&gt;What happens is the backup process makes a copy of the BLOB data on the S3 server. In the case of an engine level backup the user can specify the S3 Server that the BLOBs should be backed up to which may be a different server entirely. BLOB data is stored on the S3 server using generated names matching the pattern:&lt;br /&gt;&lt;br /&gt;&amp;#60;database_id&amp;#62;/&amp;#60;backup_no&amp;#62;/&amp;#60;cloud_ref&amp;#62;.&amp;#60;time_stamp&amp;#62;.&amp;#60;sequence_count&amp;#62;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Example&lt;/span&gt;: 1257393091/0/87.1257393139.626&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;database_id&lt;/span&gt; is the id of the database as provided by the PBMS engine.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;backup_no&lt;/span&gt; is the backup number of the BLOB. For BLOBs that are not backup copies this number is always zero. The backup number is just a sequence counter that ensures that the backup BLOBs have a unique name. All backup BLOBs from the same backup will have the same backup number. This backup number is stored in the 'Cloud_backup_no' column of the 'pbms.pbms_backup' table.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;cloud_ref&lt;/span&gt; is the reference into the 'pbms.pbms_cloud' table that refers to the S3 server and bucket in which the BLOB is stored.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;time_stamp&lt;/span&gt; is the time in seconds  at which the BLOB was created.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;sequence_count&lt;/span&gt; is just a counter to ensure that no 2 BLOBs get the same name.&lt;/li&gt;&lt;/ul&gt;When a backup is started a check is done to find an unused backup number. Then as each BLOB repository record is backed up the S3 server is sent a request to copy the BLOB to its new name with the new backup number which may also be in a different bucket or on a different server.&lt;br /&gt;&lt;br /&gt;The first step of the database recovery is to delete any BLOBs from the original database. This is done by performing the S3 equivalent of '&lt;span style="font-style: italic;"&gt;rm -r &amp;#60;database_id&amp;#62;/0/*&lt;/span&gt; ' .&lt;br /&gt;&lt;br /&gt;Recovery from an sqldump backup is just the reverse of the backup, as each BLOB repository record is written back to the repository the BLOB is copied back to its original name and location with the backup number set to zero. The 'cloud_ref' number is used to look up the S3 server location from which the original BLOB came.&lt;br /&gt;&lt;br /&gt;Recovery from an engine level backup is a bit different because the repository recovery is just a drag and drop operation. The first time the database is accessed the PBMS engines sees that the repository has just been recovered and starts the S3 BLOB recovery process. To recover the S3 BLOBs a list of all the BLOBs in the backup is made and then using the 'cloud_ref' number from the BLOB name the original location of the BLOB is found and the backed up BLOB is copied back to it.&lt;br /&gt;&lt;br /&gt;The nice thing about using S3 storage for the BLOBs is that the database BLOB repository can be backed up quite nicely just using mysqldump.&lt;br /&gt;&lt;br /&gt;When deleting old backups it is important to remember that there may be BLOBs on an S3 server that also need to be cleaned up. This is where you can make use of the 'pbms.pbms_backup' table to find the location of the backed up BLOBs and using a tool, such as the "S3 FireFox Organizer", delete them. After that the backup record can be deleted from the 'pbms.pbms_backup' table. I could have had the PBMS engine delete all the backed up BLOBs for a backup when the record was deleted from the 'pbms.pbms_backup' table but I thought that that could lead to lost data if the user did not realize the side effects of deleting a backup record.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-383176410971588446?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/383176410971588446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=383176410971588446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/383176410971588446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/383176410971588446'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/11/pbms-backup-and-s3-storage.html' title='PBMS backup and S3 storage'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2555970065377414593</id><published>2009-11-05T15:31:00.000-08:00</published><updated>2009-11-05T18:46:43.803-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='S3'/><category scheme='http://www.blogger.com/atom/ns#' term='Cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><title type='text'>PBMS Cloud storage is back!</title><content type='html'>Hi,&lt;br /&gt;&lt;br /&gt;Support for S3 BLOB storage has now been fully integrated into the PBMS engine. It works in much the same way that I mentioned in an earlier post but with some important changes so I will explain it all again here.&lt;br /&gt;&lt;br /&gt;When using S3 BLOB storage with PBMS the BLOB reference tracking and metadata is handled the same as before in that they are stored in the BLOB record in the repository, but the actual BLOB is stored on an S3 server.&lt;br /&gt;&lt;br /&gt;To setup S3 storage you need to add an S3 cloud reference record to the pbms.pbms_cloud table provided by PBMS. For example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;INSERT INTO pbms.pbms_cloud(ID, Server, bucket, PublicKey, PrivateKey) VALUES(16, "S3.amazonaws.com", "PBMS-Test", "abc123", "amjr15vWq");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then you need to tell PBMS which database should use S3 cloud storage for its BLOBs. This is done by updating a couple of records in the pbms_variable table that PBMS provides for each user database. For example to setup the database "myDB" for S3 cloud storage you would do the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;UPDATE myDB.pbms_variable set value = "16" where name = "S3-Cloud-Ref";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;UPDATE myDB.pbms_variable set value = "CLOUD" where name = "Storage-type";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The database "myDB" is now setup for cloud storage. All BLOB data will now be stored in the bucket "PBMS-Test" on the S3 server "S3.amazonaws.com".&lt;br /&gt;&lt;br /&gt;This diagram shows the steps taken when the PBMS client library uploads a BLOB to the PBMS repository using S3 cloud storage. All of these steps are performed by one call the the PBMS client lib and the client application knows nothing about the type of BLOB storage being used:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ESrUDY1Mluc/SvOCT_YAsZI/AAAAAAAAACE/xVUZjnTyv9I/s1600-h/BLOB_Insert.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_ESrUDY1Mluc/SvOCT_YAsZI/AAAAAAAAACE/xVUZjnTyv9I/s400/BLOB_Insert.jpg" alt="" id="BLOGGER_PHOTO_ID_5400803658088624530" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 1&lt;/span&gt;: The BLOB metadata is sent to the PBMS engine.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 2&lt;/span&gt;: A repository record is created containing the BLOB metadata.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 3&lt;/span&gt;: A reply is sent back to the client containing the BLOB reference which is passed back up to the client application to be inserted into the user's table in place of the BLOB. An  S3 authorization signature is also returned to the client. The authorization signature is generated by the PBMS engine using the Public/Private keys for the S3 server to sign the BLOB upload request.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 4&lt;/span&gt;: The PBMS client library uses the authorization signature to upload the BLOB to the S3 server.&lt;/li&gt;&lt;/ul&gt;Alternatively the BLOB can be inserted directly into the user's table in which case the PBMS engine will upload it to the S3 server. This is not the preferred way of doing things  because it forces the MySQL server to handle the BLOB data, which is what we are trying to avoid by using the PBMS engine.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is how the BLOB is accessed. Keep in mind that all the client application does is provide the PBMS lib with a PBMS BLOB reference as it currently does and receives the BLOB in return. It knows nothing about the cloud.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ESrUDY1Mluc/SvODkQXamWI/AAAAAAAAACM/IRGD2q0t1BQ/s1600-h/BLOB_Retrieval.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_ESrUDY1Mluc/SvODkQXamWI/AAAAAAAAACM/IRGD2q0t1BQ/s320/BLOB_Retrieval.jpg" alt="" id="BLOGGER_PHOTO_ID_5400805037039065442" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 1&lt;/span&gt;: A BLOB request containing a PBMS BLOB reference is sent to the PBMS engine’s HTTP server.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 2&lt;/span&gt;: The BLOB’s repository record is read from local storage.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 3&lt;/span&gt;: An HTTP redirect reply is sent back to the client redirecting the request to the BLOB stored in the cloud. The metadata associated with the BLOB is returned to the client in the reply’s HTTP headers. The redirect URL is an authenticated query string that gives the client time limited access to the BLOB data. Use of an authenticated query string allows the data in the cloud to have access protection without requiring the client applications to know the private key normally required to get access. &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 4&lt;/span&gt;: The redirect is followed to the cloud and the BLOB data is retrieved.&lt;/li&gt;&lt;/ul&gt;The beauty of this system is that the client applications need never know how or where the actually BLOB data is stored and since the BLOB transfer is all directly between the client and the S3 server, the BLOB data doesn't need to be handled at all by the machine on which the MySQL server is running.&lt;br /&gt;&lt;br /&gt;Because the BLOB repository records indirectly refer back to the S3 server via the pbms_cloud table, the administrator is free to move the BLOB data between S3 servers and/or buckets with out having to do anything more than updating the record in the pbms_cloud table. For example given the following setup:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ESrUDY1Mluc/SvOEUv6hTpI/AAAAAAAAACU/PcO6F39tYFk/s1600-h/BLOB_location1.jpg"&gt;&lt;img style="margin: 1px auto 10px; display: block; text-align: left; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_ESrUDY1Mluc/SvOEUv6hTpI/AAAAAAAAACU/PcO6F39tYFk/s320/BLOB_location1.jpg" alt="" id="BLOGGER_PHOTO_ID_5400805870141525650" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;all that would be required to relocate the BLOB data from the Amazon S3 server to the Sun S3 server would be to:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Copy the BLOB data from the amazon server to the Sun server.&lt;/li&gt;&lt;li&gt;Update the pbms_cloud table as: &lt;span style="font-style: italic;"&gt;UPDATE pbms.pbms_cloud set server = "S3.sunaws.com", Bucket = "B3" PublicKey = "zft123", PrivateKey = "abc123" where id =&lt;/span&gt; 17;&lt;/li&gt;&lt;li&gt;Delete the BLOBs on the amazon server.&lt;/li&gt;&lt;/ul&gt;resulting in:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ESrUDY1Mluc/SvOEz4stJbI/AAAAAAAAACc/--S6Fo3O-qI/s1600-h/BLOB_location2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: right; cursor: pointer; width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_ESrUDY1Mluc/SvOEz4stJbI/AAAAAAAAACc/--S6Fo3O-qI/s320/BLOB_location2.jpg" alt="" id="BLOGGER_PHOTO_ID_5400806405075445170" border="1" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I will explain how the new BLOB repository backup system works with cloud storage in another blog entry.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2555970065377414593?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2555970065377414593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2555970065377414593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2555970065377414593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2555970065377414593'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/11/pbms-cloud-storage-is-back.html' title='PBMS Cloud storage is back!'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ESrUDY1Mluc/SvOCT_YAsZI/AAAAAAAAACE/xVUZjnTyv9I/s72-c/BLOB_Insert.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2718940455709430612</id><published>2009-09-29T14:58:00.000-07:00</published><updated>2009-09-29T15:14:42.865-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OPenSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><title type='text'>PBMS will be at the OpenSQL camp in Portland Nov. 14-15</title><content type='html'>I am planning on presenting a session on PBMS at the OpenSQL camp. I am in hopes of have a chance to discuss PBMS with people and find out how they are planning on using it and what features they would like to see in it.&lt;br /&gt;&lt;br /&gt;But even if you are not interested in PBMS you should still come if for no other reason than the  &lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;free pizza&lt;/span&gt;&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;I am proud to say the PrimeBase Technologies is one of the organizations who's sponsorship money is helping to provide the free pizza.&lt;br /&gt;&lt;br /&gt;I will see you all there,&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2718940455709430612?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2718940455709430612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2718940455709430612' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2718940455709430612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2718940455709430612'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/09/pbms-will-be-at-opensql-camp-in.html' title='PBMS will be at the OpenSQL camp in Portland Nov. 14-15'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-6473493002695352772</id><published>2009-08-15T19:17:00.000-07:00</published><updated>2009-09-08T14:34:04.124-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='PBXT'/><category scheme='http://www.blogger.com/atom/ns#' term='InnoDB'/><title type='text'>PBMS version 0.5.09 has been released.</title><content type='html'>A new release of the PrimeBase Media Streaming engine is now available for download at&lt;br /&gt;&lt;a href="http://www.blobstreaming.org/"&gt;http://www.blobstreaming.org&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;The main focus of this release was to provide the features required to make PBMS production ready and with the addition of transaction support and engine level backup I think it is almost there. The engine does not yet provide engine level replication but it will in a future release.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's new:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PBMS now provides two methods to backup the BLOB repository which are documented &lt;a href="http://www.blobstreaming.org/documentation/#Backup_and_REcovery"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;PBMS now supports transactions independently of the storage engine.&lt;/li&gt;&lt;li&gt;There is now a PHP extension for PBMS. &lt;a href="http://www.blobstreaming.org/documentation/php/index.html"&gt;Check it out!&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The interface between PBMS and storage engines has been greatly simplified so that PBMS support can be added directly to MySQL or other engines such as InnoDB by applying a simple patch to the handler as talked about in an earlier blog &lt;a href="http://bpbdev.blogspot.com/2009/07/new-simplified-engine-interface-for.html"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;What's Next:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The next step is to take this version and do extensive testing to make sure it is stable. There are a few known bugs listed in the &lt;a href="http://www.blobstreaming.org/download/pbms/TODO"&gt;To-Do&lt;/a&gt; list that I need to fix and as I add more test cases and do more stress testing I am sure I will find more.&lt;br /&gt;&lt;br /&gt;The S3 Cloud support, which was mentioned &lt;a href="http://bpbdev.blogspot.com/2009/04/blob-storage-in-cloud-with-pbms.html"&gt;here&lt;/a&gt;, has been pulled out of this release and I want to get it back in as soon as possible.&lt;br /&gt;&lt;br /&gt;I also plan to make some patches available that can be applied to MySQL or InnoDB to make them PBMS enabled.&lt;br /&gt;&lt;br /&gt;And of course I need to get PBMS into Drizzle. That isn't really that much work, I have already had it running with Drizzle but I have been waiting to get a stable full feature version first. I think what I have now is close enough so I will be working on this shortly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's after that:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once I get the current version running stably with no major bugs or limitations and have taken care of the above mentioned issues,  I plan on working on the following .&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Remote repositories&lt;/span&gt;: the entire repository is stored somewhere other than in the MySQL data directory, most likely on a different machine entirely.  This is different from cloud storage in that the entire repository is stored remotely instead of just the BLOB data.  The remote repository server would be a standalone PBMS HTTP server providing clients with access to the BLOB data stored in the repository. The standalone PBMS HTTP server could in turn be using cloud storage so that the BLOB data itself was stored in a cloud.  A solution like this should be able to work with the NDBCLUSTER storage engine.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Engine level replication&lt;/span&gt;: This would be done similar to the remote repository but the data would be stored in the local repository as well as being forwarded to the slave servers.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Incremental backup&lt;/span&gt;. This allows you to basically sync the current state of the BLOB repository with that of a backup. To do this all new BLOBs and BLOB references in the current database would be added to the backup and BLOBs and BLOB references in the backup that no longer exist in the current database would be removed. In this way only the new data is copied to the backup location.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As usual if you have any questions about PBMS and BLOB storage please send them to me and I will do my best to answer them.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-6473493002695352772?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/6473493002695352772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=6473493002695352772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6473493002695352772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6473493002695352772'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/08/pbms-version-0509-has-been-released.html' title='PBMS version 0.5.09 has been released.'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-7404711761703299825</id><published>2009-07-22T14:05:00.000-07:00</published><updated>2009-07-22T15:21:30.521-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='InnoDB'/><title type='text'>New simplified engine interface for PBMS</title><content type='html'>By making PBMS transactional I have been able to greatly simplify the engine interface making it much easier for engine builders to build in support for PBMS. How much simpler is it? From the time I decided to make InnoDB PBMS enabled to when I started the rebuild of MySQL was &lt;span&gt;less than half an hour!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The same way that I added PBMS support to InnoDB it can be added directly to the MySQL server so that the PBMS engine will be used for BLOB storage for all engines regardless of if they have been enabled or not. PBMS support for drizzle will be provided via a data filter plug-in which I have yet to write but will soon.&lt;br /&gt;&lt;br /&gt;To add PBMS support all you need to do is add the file pbms_enabled.cc to your source code and add the following to your handler code. I will use the InnoDB handler code as an example:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;File ha_innodb.cc&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;#ifdef USE_PRAGMA_IMPLEMENTATION&lt;br /&gt;#pragma implementation    // gcc: Class implementation&lt;br /&gt;#endif&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;/* Include necessary InnoDB headers */&lt;br /&gt;extern "C" {&lt;br /&gt;#include "../storage/innobase/include/univ.i"&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;#include "../storage/innobase/include/ha_prototypes.h"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#define PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#include "pbms_enabled.h"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;static const long AUTOINC_OLD_STYLE_LOCKING = 0;&lt;br /&gt;static const long AUTOINC_NEW_STYLE_LOCKING = 1;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;innobase_init(&lt;/span&gt;&lt;br /&gt;/*==========*/&lt;br /&gt;           /* out: 0 on success, error code on failure */&lt;br /&gt;void    *p) /* in: InnoDB handlerton */&lt;br /&gt;{&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;err = innobase_start_or_create_for_mysql();&lt;br /&gt;&lt;br /&gt;if (err != DB_SUCCESS) {&lt;br /&gt;   my_free(internal_innobase_data_file_path,&lt;br /&gt;                    MYF(MY_ALLOW_ZERO_PTR));&lt;br /&gt;   goto error;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   PBMSResultRec result;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (!pbms_initialize("InnoDB", &amp;amp;result)) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       sql_print_error("pbms_initialize() Error: %s", result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       goto error;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;(void) hash_init(&amp;amp;innobase_open_tables,system_charset_info, 32, 0, 0,&lt;br /&gt;               (hash_get_key) innobase_get_key, 0, 0);&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;error:&lt;br /&gt;DBUG_RETURN(TRUE);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;innobase_end(handlerton *hton, ha_panic_function type)&lt;/span&gt;&lt;br /&gt;/*==============*/&lt;br /&gt;           /* out: TRUE if error */&lt;br /&gt;{&lt;br /&gt;int err= 0;&lt;br /&gt;&lt;br /&gt;DBUG_ENTER("innobase_end");&lt;br /&gt;&lt;br /&gt;#ifdef __NETWARE    /* some special cleanup for NetWare */&lt;br /&gt;if (nw_panic) {&lt;br /&gt;   set_panic_flag_for_netware();&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;if (innodb_inited) {&lt;br /&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       pbms_finalize();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;DBUG_RETURN(err);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;int&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;ha_innobase::write_row(&lt;/span&gt;&lt;br /&gt;/*===================*/&lt;br /&gt;       /* out: error code */&lt;br /&gt;uchar* record) /* in: a row in MySQL format */&lt;br /&gt;{&lt;br /&gt;int      error = 0;&lt;br /&gt;ibool    auto_inc_used= FALSE;&lt;br /&gt;ulint    sql_command;&lt;br /&gt;trx_t*   trx = thd_to_trx(user_thd);&lt;br /&gt;&lt;br /&gt;DBUG_ENTER("ha_innobase::write_row");&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   PBMSResultRec result;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   error = pbms_write_row_blobs(table, record, &amp;amp;result);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (error) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       sql_print_error( "pbms_write_row_blobs() Error: %s", result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       DBUG_RETURN(error);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   pbms_completed(table, (error == 0));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;DBUG_RETURN(error);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;ha_innobase::update_row(&lt;/span&gt;&lt;br /&gt;/*====================*/&lt;br /&gt;      /* out: error number or 0 */&lt;br /&gt;const uchar*  old_row,  /* in: old row in MySQL format */&lt;br /&gt;uchar*        new_row)  /* in: new row in MySQL format */&lt;br /&gt;{&lt;br /&gt;upd_t* uvect;&lt;br /&gt;int    error = 0;&lt;br /&gt;trx_t* trx = thd_to_trx(user_thd);&lt;br /&gt;&lt;br /&gt;DBUG_ENTER("ha_innobase::update_row");&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   PBMSResultRec result;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   error = pbms_delete_row_blobs(table, old_row, &amp;amp;result);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (error) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       sql_print_error( "update_row:pbms_delete_row_blobs() Error: %s",&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;           result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       DBUG_RETURN(error);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   error = pbms_write_row_blobs(table, new_row, &amp;amp;result);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (error) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       sql_print_error( "update_row:pbms_write_row_blobs() Error: %s",&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;           result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       goto pbms_done;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   pbms_done:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   pbms_completed(table, (error == 0));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;DBUG_RETURN(error);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;int&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;ha_innobase::delete_row(&lt;/span&gt;&lt;br /&gt;/*====================*/&lt;br /&gt;                       /* out: error number or 0 */&lt;br /&gt;const uchar*    record) /* in: a row in MySQL format */&lt;br /&gt;{&lt;br /&gt;int    error = 0;&lt;br /&gt;trx_t* trx = thd_to_trx(user_thd);&lt;br /&gt;&lt;br /&gt;DBUG_ENTER("ha_innobase::delete_row");&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   PBMSResultRec result;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   error = pbms_delete_row_blobs(table, record, &amp;amp;result);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (error) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       sql_print_error( "pbms_delete_row_blobs() Error: %s", result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       DBUG_RETURN(error);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   pbms_completed(table, (error == 0));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;DBUG_RETURN(error);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;int&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;ha_innobase::delete_table(&lt;/span&gt;&lt;br /&gt;/*======================*/&lt;br /&gt;                   /* out: error number */&lt;br /&gt;const char* name)   /* in: table name */&lt;br /&gt;{&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   /* Call pbms_delete_table_with_blobs() last because it cannot be undone. */&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (!error) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       PBMSResultRec result;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       if (pbms_delete_table_with_blobs(name, &amp;amp;result)) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;           sql_print_error( "pbms_delete_table_with_blobs() Error: %s",&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;               result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;  &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       pbms_completed(NULL, true);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;DBUG_RETURN(error);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;int&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;ha_innobase::rename_table(&lt;/span&gt;&lt;br /&gt;/*======================*/&lt;br /&gt;                  /* out: 0 or error code */&lt;br /&gt;const char* from,  /* in: old name of the table */&lt;br /&gt;const char* to)    /* in: new name of the table */&lt;br /&gt;{&lt;br /&gt;ulint   name_len1;&lt;br /&gt;ulint   name_len2;&lt;br /&gt;int     error;&lt;br /&gt;trx_t*  parent_trx;&lt;br /&gt;trx_t*  trx;&lt;br /&gt;char    norm_from[1000];&lt;br /&gt;char    norm_to[1000];&lt;br /&gt;THD*    thd = ha_thd();&lt;br /&gt;&lt;br /&gt;DBUG_ENTER("ha_innobase::rename_table");&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   PBMSResultRec result;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   error = pbms_rename_table_with_blobs(from, to, &amp;amp;result);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   if (error) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       sql_print_error( "pbms_rename_table_with_blobs() Error: %s", result.mr_message);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;       DBUG_RETURN(error);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;:&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#ifdef PBMS_ENABLED&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   pbms_completed(NULL, (error == 0));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;#endif&lt;/span&gt;&lt;br /&gt;DBUG_RETURN(error);&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Now you are probably wondering how I spent half an hour just adding that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-7404711761703299825?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/7404711761703299825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=7404711761703299825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/7404711761703299825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/7404711761703299825'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/07/new-simplified-engine-interface-for.html' title='New simplified engine interface for PBMS'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2988430650706543213</id><published>2009-07-21T11:33:00.000-07:00</published><updated>2009-07-21T11:39:04.059-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='PBXT'/><title type='text'>PBMS is transactional!</title><content type='html'>The PBMS engine now has built in support for transaction so that if you reference or dereference BLOBs during a transaction the changes you made will be committed or rolled back with the transaction. Up until now PBMS had depended on the host engine to handle transactions and inform it what needed to be done in the event of a rollback. &lt;br /&gt;&lt;br /&gt;I have implemented transaction support by adding a circular transaction log and transaction cache.  The circular transaction log is dynamic and can grow and shrink as required. The transaction records are all small (30 byte) fixed length records so the log doesn’t need to be that large to be able to handle a lot of transactions. A head and tail pointer are maintained to indicate where the head and tail of the circular log is. If the circular log becomes full then the records just overflow and are written to the end of the log. Once the transaction reader has caught up after an overflow has occurred it simply resizes the circular log to include the overflow and everything continues as normal with a larger circular log. The circular log will be reduced to its normal size once free space becomes available at the end of the log.&lt;br /&gt;&lt;br /&gt;If anyone has any use for something like this them selves it has been written as a standalone module so it would not be to difficult to pull it out and build it into something else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2988430650706543213?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2988430650706543213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2988430650706543213' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2988430650706543213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2988430650706543213'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/07/pbms-is-transactional.html' title='PBMS is transactional!'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-970029188435503067</id><published>2009-05-27T16:34:00.000-07:00</published><updated>2009-05-29T11:17:53.225-07:00</updated><title type='text'>Backing up BLOBs</title><content type='html'>The PBMS BLOB repositories can now be backed up with mysqldump.&lt;br /&gt;&lt;br /&gt;A new system table ‘pbms_dump’ contains 1 row for each repository record. Each row consists of 1 column which is a BLOB. The content of this table has no purpose other than for the use in repository backup.  By inserting the data back into this table the repository is recovered. Before doing the backup the pbms_dump system table needs to be discovered, to do this execute the command “select * from pbms_dump where false”. After doing this then mysqldump will include it in backups. Be sure to use the “—hex-blob” option. For example:&lt;br /&gt;&lt;br /&gt;Mysqldump –u root –hex-blob mydatabase &gt; mydatabase.sql&lt;br /&gt;&lt;br /&gt;Before recovering the database you need to notify PBMS that a recovery operation is in progress so that the recovery of the tables containing the BLOB references do not increment the BLOB reference count. This notification is done by setting a bool flag in a new system table (I like system tables ☺) pbms_variable. To restore a database perform the following operations:&lt;br /&gt;&lt;br /&gt;----------------------------&lt;br /&gt;create database recovtest;&lt;br /&gt;use recovtest;&lt;br /&gt;&lt;br /&gt;update pbms_variable set Value = "true" where Name = "Restoring-Dump";&lt;br /&gt;source mydatabase.sql;&lt;br /&gt;update pbms_variable set Value = "false" where Name = "Restoring-Dump";&lt;br /&gt;-------------------------------&lt;br /&gt;&lt;br /&gt;I am also planning on implementing the engine level backup and recovery supported in MySQL 6.o as well as an internal backup method that will produce a backup that you can  recover just by dragging and dropping it into the ‘pbms’ folder where your database folders are located.&lt;br /&gt;&lt;br /&gt;The internal backup will run asynchronously in the background and will not block normal operations of the database including adding and deleting BLOBs. The way that it would work is that the administrator would lock the tables containing the BLOB references and back them up. Sometime during the backup, before releasing the locks, the asynchronously PBMS backup of the database would be started. Progress of the backup could be monitored via a pbms_status table.&lt;br /&gt;&lt;br /&gt;The version supporting mysqldump is in the PBMS branch "~pbms-core/pbms/cloud" on launchpad. Be warned though that this is a development branch with everything that implies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-970029188435503067?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/970029188435503067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=970029188435503067' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/970029188435503067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/970029188435503067'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/05/backing-up-blobs.html' title='Backing up BLOBs'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2538573820365280928</id><published>2009-04-01T08:35:00.000-07:00</published><updated>2009-04-01T10:41:34.791-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='PBXT'/><title type='text'>BLOB storage in the cloud with PBMS</title><content type='html'>I am pleased to announce a cloud storage version of the PBMS engine.&lt;br /&gt;&lt;br /&gt;What I have created is a version of PBMS that stores the BLOB data in a cloud and when a request for the data comes in the client is sent a redirect to get the BLOB directly from the cloud. The BLOB reference tracking and metadata is handled the same as before in that they are stored in the BLOB record in the repository but the actual BLOB is stored somewhere else.&lt;br /&gt;&lt;br /&gt;This has several advantages over storing the BLOB in the repository record:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ESrUDY1Mluc/SdOjxeYYuHI/AAAAAAAAAB0/ZddhUlQ3R3g/s1600-h/Slide3.jpg"&gt;&lt;/a&gt;&lt;ol&gt;&lt;li&gt;It reduces the disk storage requirement of the database server’s machine.&lt;/li&gt;&lt;li&gt;It reduces the bandwidth requirement of the database server’s machine.&lt;/li&gt;&lt;/ol&gt;The beauty of it is that the client application doesn’t need to know anything about the cloud because it is all handled by the PBMS engine and PBMS lib.&lt;br /&gt;&lt;br /&gt;Here is a diagram showing how an insert works:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ESrUDY1Mluc/SdOkLLyThlI/AAAAAAAAAB8/tGTAY0iTPTE/s1600-h/Slide2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_ESrUDY1Mluc/SdOkLLyThlI/AAAAAAAAAB8/tGTAY0iTPTE/s400/Slide2.jpg" alt="" id="BLOGGER_PHOTO_ID_5319776096903988818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 1&lt;/span&gt;: The BLOB is sent to the PBMS engine. Ideally this is done by using the PBMS lib to send it to the PBMS engine’s HTTP server and then inserting the returned BLOB reference  into the table in place of the BLOB. Optionally the BLOB can be insert  directly with an ‘insert’ statement and the PBMS engine will replace it with a BLOB reference internally. The first method is preferable though since it impacts server performance less and reduces the server’s memory usage because the BLOB is streamed into the repository file and is never stored in memory.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 2&lt;/span&gt;: A repository record is created containing the BLOB data.&lt;/li&gt;&lt;/ul&gt;(Steps 1 and 2 are the same for both cloud and none-cloud versions of PBMS.)&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 3&lt;/span&gt;: The BLOB is scheduled for upload to the cloud. A separate thread, called the ‘cloud’ thread, which operates in the background, performs the upload. &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 4&lt;/span&gt;: The local BLOB data is scheduled for deletion. This action can be delayed for a time to ensure that the data is actually accessible by the clients before the local copy of the BLOB is deleted. The repository record remains but the space used by the actual BLOB is added to the repository’s garbage count and the space will be reclaimed later by the PBMS compactor thread.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Here is how the BLOB is accessed. Keep in mind that all the client application does is provide the PBMS lib with a PBMS BLOB reference as it currently does and receives the BLOB in return. It knows nothing about the cloud.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ESrUDY1Mluc/SdOjxeYYuHI/AAAAAAAAAB0/ZddhUlQ3R3g/s1600-h/Slide3.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/_ESrUDY1Mluc/SdOjxeYYuHI/AAAAAAAAAB0/ZddhUlQ3R3g/s400/Slide3.jpg" alt="" id="BLOGGER_PHOTO_ID_5319775655218952306" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 1&lt;/span&gt;: A BLOB request containing a PBMS BLOB reference is sent to the PBMS engine’s HTTP server.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 2&lt;/span&gt;: The BLOB’s repository record is read from local storage.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 3&lt;/span&gt;: An HTTP redirect reply is sent back to the client redirecting the request to the BLOB stored in the cloud. The metadata associated with the BLOB is returned to the client in the reply’s HTTP headers. The redirect URL is an authenticated query string that gives the client time limited access to the BLOB data. Use of an authenticated query string allows the data in the cloud to have access protection without requiring the client applications to know the private key normally required to get access. &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Step 4&lt;/span&gt;: The redirect is followed to the cloud and the BLOB data is retrieved.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Note the absence of lines passing through the MySQL server. All of this is done outside of the database server, freeing the database server to process database queries rather than serve up BLOB data.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The current version I am working on uses Amazon S3 storage but the cloud access is done via a fairly simple class interface, which should be easy to implement for any Amazon S3 - like interface.&lt;br /&gt;&lt;br /&gt;&lt;plug&gt;&lt;br /&gt;If you want to find out more be sure to attend my talk at the MySQL conference “BLOB Streaming: Efficient Reliable BLOB Handling for all Storage Engines “.&lt;br /&gt;&lt;/plug&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2538573820365280928?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2538573820365280928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2538573820365280928' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2538573820365280928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2538573820365280928'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/04/blob-storage-in-cloud-with-pbms.html' title='BLOB storage in the cloud with PBMS'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ESrUDY1Mluc/SdOkLLyThlI/AAAAAAAAAB8/tGTAY0iTPTE/s72-c/Slide2.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-5528074217623460906</id><published>2009-03-26T09:14:00.000-07:00</published><updated>2009-03-26T10:05:25.071-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='PBXT'/><title type='text'>The PrimeBase BLOB Streaming (PBMS) engine alpha version 5.08 is ready</title><content type='html'>Alpha version 5.08 of the BLOB streaming engine for MySQL has been released. You can download the source code from &lt;a href="http://www.blobstreaming.org/download"&gt;www.blobstreaming.org/download&lt;/a&gt;. The documentation has also been updated.&lt;br /&gt;&lt;br /&gt;What's new in 5.08:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;All PBMS data is stored under a '&lt;span style="font-weight: bold;"&gt;pbms&lt;/span&gt;' directory in the MySQL server's data directory rather than in the database directories them selves.&lt;/li&gt;&lt;li&gt;This version now builds with Drizzle and can be loaded as a 'Blobcontainer' plug-in. &lt;/li&gt;&lt;li&gt;Added the possibility of storing BLOB metadata along with the BLOB in the repository.&lt;/li&gt;&lt;li&gt;Added the possibility of assigning an alias to a BLOB, which can then be used to retrieve the BLOB instead of using the engine generated URL.&lt;/li&gt;&lt;li&gt;Added an updateable system table '&lt;span style="font-weight: bold;"&gt;pbms_metadata_header&lt;/span&gt;' to control which HTTP headers are stored as metadata.&lt;/li&gt;&lt;li&gt;Added an updateable system table '&lt;span style="font-weight: bold;"&gt;pbms_metadata&lt;/span&gt;' that contains all the metadata associated with the BLOBs.&lt;/li&gt;&lt;li&gt;New PBMS API functions have been added to set and get BLOB metadata.&lt;/li&gt;&lt;li&gt;A new PBMS API function has been added to allow applications to get the BLOB metadata with out getting the actual BLOB.&lt;/li&gt;&lt;li&gt;Added some new fields to the '&lt;span style="font-weight: bold;"&gt;pbms_repository&lt;/span&gt;' system table.&lt;/li&gt;&lt;li&gt;Removed the raw BLOB data from the '&lt;span style="font-weight: bold;"&gt;pbms_repository&lt;/span&gt;' system table and placed it in its own table, '&lt;span style="font-weight: bold;"&gt;pbms_blob&lt;/span&gt;'.&lt;/li&gt;&lt;li&gt;Dropping a database containing PBMS BLOBS referenced from non-PBXT tables no longer requires special handling.&lt;/li&gt;&lt;li&gt; System tables can now be selected with an 'order by' clause.&lt;/li&gt;&lt;/ul&gt;As you can see a lot of work has been done on it and a lot of things have changed. I have already talked about most of the major changes in my previous  2 BLOG postings but I recommend having a look at the &lt;a href="http://www.blobstreaming.org/documentation"&gt;documentation&lt;/a&gt; for more details.&lt;br /&gt;&lt;br /&gt;A few things to watch for in the new version:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The location and format of the BLOB repository files has changed. This means that if you are using an older version you will need to import the data from the server using the older version of PBMS into tables on a server running the new version. Feel free to contact me if you have any questions about this. I will try to maintain backward compatibility with older versions of PBMS but until the code is no longer alpha I can not guarantee this.&lt;/li&gt;&lt;li&gt;A patch was added to the PBXT engine to prevent a crash when shutting down MySQL. The PBXT version '&lt;span style="font-weight: bold;"&gt;1.0.07m-rc&lt;/span&gt;' contains this patch and is available for download with the the PBMS engine.&lt;/li&gt;&lt;li&gt;There remains an unsolved problem that can lead to PBXT hanging when a PBXT table containing longblobs is dropped and the PBMS engine is being used for BLOB storage.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;As usual if you have any questions about PBMS and BLOB storage please send them to me and I will do my best to answer them.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-5528074217623460906?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/5528074217623460906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=5528074217623460906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5528074217623460906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5528074217623460906'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/03/primebase-blob-streaming-pbms-engine.html' title='The PrimeBase BLOB Streaming (PBMS) engine alpha version 5.08 is ready'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-4724149406280167824</id><published>2009-03-04T12:03:00.000-08:00</published><updated>2009-03-04T14:24:15.011-08:00</updated><title type='text'>PBMS supports BLOB metadata and aliases</title><content type='html'>The PrimeBase PBMS engine now supports user defined metadata.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;When the PBMS engine receives a BLOB the HTTP header tag value pairs are stored with the BLOB as metadata. To restrict which headers are stored as metadata an updatable system table '&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;pbms&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_http_fields&lt;/span&gt;' is provided in which users can add the names of the headers that are to be treated as metadata. When the BLOB is retrieved from the engine the metadata is sent back along with the BLOB as HTTP headers in the same way that it was received.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The metadata can be accessed from within the database via the '&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;pbms&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;matadata&lt;/span&gt;' system table or altered by performing &lt;span class="Apple-style-span" style="font-style: italic;"&gt;inserts&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-style: italic;"&gt;updates&lt;/span&gt;, or &lt;span class="Apple-style-span" style="font-style: italic;"&gt;deletes&lt;/span&gt; on the table.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A BLOB alias is a special metadata field that allows you to associate a database wide unique name with the BLOB which can then be used later to retrieve it. If you are familiar with Amazon S3 storage it works in a similar manner where you can think of the database as the S3 bucket and the BLOB alias as the S3 key.  To fetch the BLOB back using the alias you use a URL with the format &lt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;database&lt;/span&gt;&gt;/&lt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;alias&lt;/span&gt;&gt;. The following is an example using 'curl' to send a BLOB with alias 'MyBLOB' to the PBMS engine and then fetch it back again:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;curl -H "PBMS_BLOB_ALIAS:MyBLOB" -d "A BLOB with alias" "http://localhost:8080/test"&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Returning:&lt;/div&gt;&lt;div&gt;~*test/_1-632-4934f86e-0*17&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;curl -D - "http://localhost:8080/test/MyBLOB"&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Returning:&lt;/div&gt;&lt;div&gt;&lt;div&gt;HTTP/1.1 200 OK&lt;/div&gt;&lt;div&gt;PBMS_CHECKSUM: A3762FF16159FAB246EBA2BE50F98CF4&lt;/div&gt;&lt;div&gt;PBMS_BLOB_SIZE: 17&lt;/div&gt;&lt;div&gt;PBMS_LAST_ACCESS: 1236200654&lt;/div&gt;&lt;div&gt;PBMS_ACCESS_COUNT: 0&lt;/div&gt;&lt;div&gt;PBMS_CREATION_TIME: 1236200654&lt;/div&gt;&lt;div&gt;PBMS_BLOB_ALIAS: MyBLOB&lt;/div&gt;&lt;div&gt;Content-Length: 17&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A BLOB with alias&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;In this example the BLOB has been uploaded to the PBMS engine but not yet referenced so it will be automatically deleted after a preset time. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you can see several custom headers have been added to the reply:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;CHECKSUM&lt;/span&gt; is the MD5 checksum of the BLOB data.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_BLOB_SIZE&lt;/span&gt; is the size of the BLOB data in bytes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_LAST_ACCESS&lt;/span&gt; is the last access time of the BLOB in seconds since Jan. 1 1970.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_ACCESS_COUNT&lt;/span&gt; is the number of times the BLOB has been downloaded.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;_CREATION_TIME&lt;/span&gt; is the creation time of the BLOB in seconds since Jan. 1 1970.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;It is also possible to fetch back just the header info with out the BLOB data, example:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;c&lt;span class="Apple-style-span" style="font-style: italic;"&gt;url -H "PBMS_RETURN_INFO_ONLY:yes" -D - "http://localhost:8080/test/MyBLOB"&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Returning:&lt;/div&gt;&lt;div&gt;&lt;div&gt;HTTP/1.1 200 OK&lt;/div&gt;&lt;div&gt;PBMS_CHECKSUM: A3762FF16159FAB246EBA2BE50F98CF4&lt;/div&gt;&lt;div&gt;PBMS_BLOB_SIZE: 17&lt;/div&gt;&lt;div&gt;PBMS_LAST_ACCESS: 1236200654&lt;/div&gt;&lt;div&gt;PBMS_ACCESS_COUNT: 0&lt;/div&gt;&lt;div&gt;PBMS_CREATION_TIME: 1236200654&lt;/div&gt;&lt;div&gt;PBMS_BLOB_ALIAS: MyBLOB&lt;/div&gt;&lt;div&gt;Content-Length: 0&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;The PBMS BLOB metadat enables users to store BLOB specific data with the BLOB and have it returned to them with out having to create a separate database table to store it and then execute separate SQL command to update it and retrieve it when ever they upload or download a BLOB. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The BLOB alias allows users to generate their own names for BLOBs which they can then use to access the BLOB without having to make a call to the database to get the PBMS generated URL.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-4724149406280167824?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/4724149406280167824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=4724149406280167824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/4724149406280167824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/4724149406280167824'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/03/pbms-supports-blob-metadata-and-aliases.html' title='PBMS supports BLOB metadata and aliases'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-8821103418203774059</id><published>2009-02-26T07:01:00.000-08:00</published><updated>2009-02-26T08:09:29.368-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='BLOBS'/><category scheme='http://www.blogger.com/atom/ns#' term='PBMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Drizzle'/><category scheme='http://www.blogger.com/atom/ns#' term='PBXT'/><title type='text'>PBMS supports Drizzle</title><content type='html'>The PBMS engine now works with Drizzle. Well actually it has been working with Drizzle for several months since I have been using Drizzle as my 'host' server while adding new features to the engine. I will tell you about the new features in future posts.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hooks for a 'blobcontainer' type plug-in have been added to Drizzle that allow a plug-in to catch insert. update, or delete operations on BLOB columns in any table and handle the BLOB storage itself. The plug-in gets called above the storage engine level so it is independent of the storage engines. This is very similar to the way that PBMS works in MySQL 5.1 with engines other than PBXT where it uses triggers to perform the same function. But the way it is done with Drizzle is a lot more efficient.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So in Drizzle the PBMS engine is both a 'blobcontainer' plug-in as well as a storage engine. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Surprisingly little needed to be done to the PBMS engine to get it to build with Drizzle. It was a big help having the PBXT engine already ported to Drizzle so for a large part all I needed to do was look to see what Paul had done and do the same. The same source code is used for both the Drizzle and MySQL builds and the build procedure is the same. When you configure the engine different build flags will automatically be set depending if the target is a MySQL source tree or a Drizzle source tree. But before you try doing a build yourself you should know that the 'blobcontainer' plug-in support has not been merged into the main Drizzle build branch yet. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The one drawback to the way the 'blobcontainer' plug-in works currently is that it take a shotgun  approach to BLOB management in that either all blobs in all tables are stored using the 'blobcontainer' plug-in or none are. This is because there is no way of telling the plug-in which BLOB columns are to be stored using the plug-in and which are not. I am in hopes that some way will be found so that BLOB columns can be selectively handled by the 'blobcontainer' plug-in. Possible ways of doing this would be to have a special BLOB column type for BLOBs to be stored with the 'blobcontainer' plug-in or provide a column attribute to signal how the BLOB data is to be stored. In MySQL 5.1 only longblob columns are stored using the PBMS engine. I have no doubt though that a good solution for this problem will be found before long.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Barry&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-8821103418203774059?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/8821103418203774059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=8821103418203774059' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/8821103418203774059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/8821103418203774059'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2009/02/pbms-supports-drizzle.html' title='PBMS supports Drizzle'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-2614271187239076248</id><published>2008-11-05T17:15:00.000-08:00</published><updated>2008-11-05T17:46:35.520-08:00</updated><title type='text'>Amazon S3 file transfer daemon</title><content type='html'>This is a project that I have been working on that I have just uploaded to launchpad. It is not directly related to my work on the BLOB streaming engine for MySQL but it does contain code and ideas that I hope to work into it. The project name on launchpad is 's3daemon'.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Amazon S3 file transfer daemon is a daemon process that runs in the background and monitors folders. When it finds a file in one of the folders that matches a specific pattern it transfers that file to S3 storage and then removes the local copy. The folders monitored and the patterns searched for are controlled by a configuration file.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Included with the daemon is an apache module that handles requests for files in the folders monitored by the daemon. If a request comes in for a file and the file cannot be found locally the caller is sent a redirect to get the file directly from the S3 server.  The redirect contains a signature created by the module using a public/private key combination that tells the S3 server that the caller is authorized to get the requested file. Included in the authorization is a time stamp that limits how long the URL/signature combination is good for.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am thinking that a BLOB streaming engine that handled BLOBs in a similar manner may be of interest to people storing a large amount of image data. Such an engine would allow the creation and deletion of the data to be controlled by the database while the actual BLOBs are stored in S3 storage. This also decreases the bandwidth requirements of the server machine because the actual data will be served up by the S3 server.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-2614271187239076248?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/2614271187239076248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=2614271187239076248' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2614271187239076248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/2614271187239076248'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/11/amazon-s3-file-transfer-daemon.html' title='Amazon S3 file transfer daemon'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-9056471489096486887</id><published>2008-10-20T09:39:00.000-07:00</published><updated>2008-10-20T10:07:28.573-07:00</updated><title type='text'>Using config.status to build outside the tree</title><content type='html'>I just thought I would share some of my discoveries. You may already have known this but I didn't.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In recent releases both the PBMS and PBXT engines have been using a configuration flag "--with-mysql" to tell the build where to find the MySQL tree. We then looked inside the 'config.status' file generated when MySQL was configured to get the build options, most importantly the compiler options used. We had been doing this using 'grep' and 'sed'. The problem we soon discovered was that the format of the 'config.status' file changes quit frequently with different versions of 'autoconf'. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With the help of the good people on the 'autoconf' forum I discovered that you can ask 'config.status' to give you the value of a single substitution. So to get the value for CFLAGS you enter:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;echo '@CFLAGS@' | config.status --file-&lt;/span&gt;&lt;/div&gt;&lt;div&gt;and it will print out a line with the CFLAGS.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I understand that this feature which has always existed is now being added to the 'autoconf' documentation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Using this when configuring  your build guarantees that your compiler options match that of MySQL and avoids those nasty bugs where structure alignments do not match because of different compiler settings.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I hope this helps someone out there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Barry&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-9056471489096486887?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/9056471489096486887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=9056471489096486887' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/9056471489096486887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/9056471489096486887'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/10/using-configstatus-to-build-outside.html' title='Using config.status to build outside the tree'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-9043365221721842026</id><published>2008-10-14T14:20:00.000-07:00</published><updated>2008-10-16T10:49:40.808-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PBMS MySQL PBXT BLOBS'/><title type='text'>Ideas for BLOB streaming</title><content type='html'>Hi,&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How that I have the latest release of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;PBMS&lt;/span&gt; out the door I thought I would post some of the ideas I have had for possible ways in which the BLOB streaming engine could be expanded upon. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What if the BLOB streaming engine supported the idea of having it's own BLOB storage engines that could be plugged into it the same way that storage engines are plugged into MySQL. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;API&lt;/span&gt; for these BLOB storage engines would be dead simple, all they would need to support would be a '&lt;span class="Apple-style-span" style="font-style: italic;"&gt;get&lt;/span&gt;', '&lt;span class="Apple-style-span" style="font-style: italic;"&gt;put&lt;/span&gt;', and '&lt;span class="Apple-style-span" style="font-style: italic;"&gt;delete&lt;/span&gt;' method. The BLOB streaming engine would handle the reference counting and still provide the simple HTTP server for direct access to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;BLOBs&lt;/span&gt; but the BLOB engines would handle how and where the actual BLOB data would be stored.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Currently the blob data is stored locally in blob repository files, which is very efficient but may not be ideal for some applications. Here are a few ideas I have had for possible BLOB storage engines:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;File Storage&lt;/span&gt;: This storage engine would just store the blobs in individual files. It may be of interest to applications where they want to be able to directly grab the data such a web application where the data is directly read by the web server.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Amazon S3 Storage&lt;/span&gt;: This storage engine would store the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;BLOBs&lt;/span&gt; in Amazon S3 buckets. This BLOB storage engine would be of interest to applications that deal with massive amounts of data and need a highly scalable storage solution.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Mirrored Storage&lt;/span&gt;: This storage engine would replicate the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;BLOBs&lt;/span&gt; to multiple geographical locations so that requests for the data could be directed to the closest mirrored site.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Load Balancing Storage&lt;/span&gt;: This storage engine would have the ability to move the BLOB data around to from one storage location to another to try to optimize it's access time or more evenly distribute the storage load on different servers.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Wally Storage&lt;/span&gt;: This engine wouldn't actually store anything and would reply to any request for data that it will have it for them by Wednesday. This would be of interest to applications that are forced to store data that they know nobody will ever actually want.&lt;/li&gt;&lt;/ul&gt;To allow for more flexibility in the BLOB storage engines the BLOB streaming engine would have to be able to handle a redirect reply from the BLOB storage engines. This redirect could be handled inside of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;PBMS&lt;/span&gt; client &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;API&lt;/span&gt; so that an application requesting a BLOB via the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;API&lt;/span&gt; would never need to know anything about the redirect that took place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This concept would allow the manner and location in which &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;BLOBs&lt;/span&gt; are stored to be completely decoupled from the database and database server.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Barry&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-9043365221721842026?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/9043365221721842026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=9043365221721842026' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/9043365221721842026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/9043365221721842026'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/10/ideas-for-blob-streaming.html' title='Ideas for BLOB streaming'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-1486330560475397553</id><published>2008-10-14T12:26:00.000-07:00</published><updated>2008-10-14T13:24:52.465-07:00</updated><title type='text'>Alpha release v05.06 of the BLOB streaming engine</title><content type='html'>&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/div&gt;Alpha version 5.06 of the BLOB streaming engine for MySQL has been released. You can download the source code from www.blobstreaming.org/download. The documentation has also been updated.&lt;br /&gt;&lt;br /&gt;What's new in 5.06:&lt;div&gt;&lt;ul&gt;&lt;li&gt;The BLOB streaming engine can now be used with MyISAM tables as well as tables created by any other MySQL storage engine. &lt;/li&gt;&lt;li&gt;The name of the PrimeBase BLOB streaming engine has been changed from &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;MyBS&lt;/span&gt; to &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt; which stands for "PrimeBase Media Streaming".&lt;/li&gt;&lt;/ul&gt;This version introduces a couple of new term:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;streaming-enabled table&lt;/span&gt;: This is any table created by a streaming-enabled engine such as &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBXT&lt;/span&gt;, or has triggers defined on blob referencing columns that notify the PBMS engine when BLOB references are inserted, updated, and deleted.&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;BLOB reference column&lt;/span&gt;: This is a column in a stream-enabled table that contains PBMS BLOB references and notifies the PBMS engine when data is inserted, updated, or deleted from the column.&lt;/li&gt;&lt;/ul&gt;The big news though is that as of this version you no longer need to have PBXT installed in order to use the PBMS engine. The PBMS engine provides a set of UDFs and client API functions that enable it to be used with tables created by any storage engine. The following is an example of how to create a streaming enabled MyISAM table:&lt;/div&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-style: italic; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Create table x.foo(c1 integer, c2 longblob) ENGINE = MYISAM&lt;span class="Apple-style-span" style="font-style: italic; "&gt;;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;create trigger x.foo_insert_trig BEFORE INSERT on x.foo for each row BEGIN set NEW.c2 = pbms_insert_blob_trig("x", "foo", 2, NEW.c2); END&lt;/p&gt;&lt;p&gt;create trigger x.foo_update_trig BEFORE UPDATE on x.foo for each row BEGIN set NEW.c2 = pbms_update_blob_trig("x", "foo", 2, OLD.c2, NEW.c2); END&lt;/p&gt; &lt;p&gt;create trigger x.foo_delete_trig BEFORE UPDATE on x.foo for each row BEGIN declare dummy integer; set dummy = pbms_delete_blob_trig("x", "foo", 2, OLD.c2); END&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;As a result of the name change you will see that any use of the letters 'mybs' has been changed to 'pbms' throughout the code and documentation.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of lesser importance but also of note: I have become the official contact person for the BLOB streaming engine. Paul is still very much involved with it but is currently concentrating his efforts on the PBXT engine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Barry&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-1486330560475397553?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/1486330560475397553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=1486330560475397553' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/1486330560475397553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/1486330560475397553'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/10/alpha-release-v0506-of-blob-streaming.html' title='Alpha release v05.06 of the BLOB streaming engine'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-6290598891370578718</id><published>2008-10-10T15:13:00.000-07:00</published><updated>2008-10-10T16:06:46.660-07:00</updated><title type='text'>PrimeBase PBMS does MYISAM</title><content type='html'>Hi,&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I just&lt;span&gt;&lt;span&gt; pushed a &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;/span&gt;version of PBMS up onto launchPad that works with any storage engine. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The new version provides a set of UDFs and API functions that allow you to set triggers on longblob columns so that the table can be used with the PBMS engine the same way a PBXT table would.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The following has been added to the API:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt;/* Functions used for non PBMS enabled tables. */&lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt;/*&lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt; * pbms_init_udfs() &lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt; * Declares the PBMS UDFs on the server if they do not already exist.&lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt; *&lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt; * Equivalent UFD: NONE&lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_init_udfs(MYSQL *mysql);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p color="#236e25" style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; "&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * pbms_enabled() &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Returns 'true' if the 'engine' is PBMS enabled i.e. provides direct support for PBMS. &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * So far the PBXT engine is the only PBMS enabled engine out there. Hopefully that will change.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; *&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Equivalent UFD: pbms_enabled_engine(engine)&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_enabled(MYSQL *mysql, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *engine, pbms_bool *enabled);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * pbms_init_table() &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Creates triggers on any 'longblob' columns in the table that will notify the PBMS engine when blob PBMS  &lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * references are inserted, deleted, or updated. If 'no_blobs_ok' is 'false' then an error is reported if &lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * no 'longblob' columns are found. If 'no_blobs_ok' is 'true' and then no error is reported if no 'longblob'&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * columns are found and no action is taken.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; *&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Equivalent UFD: NONE&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_init_table(&lt;span style="color:#760f50;"&gt;struct&lt;/span&gt; st_mysql *mysql, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *database, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *table, pbms_bool no_blobs_ok);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * pbms_reset_table_blobs() &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * This is similar to  pbms_init_table() except that it is meant to be called if an alter table has been done on&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * a table that contains blobs being managed by PBMS and either a 'longblob' column has been added or dropped, or&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * the ordinal position of a 'longblob' column has changed.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; *&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Equivalent UFD: NONE&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_reset_table_blobs(&lt;span style="color:#760f50;"&gt;struct&lt;/span&gt; st_mysql *mysql, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *database, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *table);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * pbms_drop_table_blobs() &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * This function is called after a table has been dropped to notify PBMS to remove all blob references from that&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * table.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; *&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Equivalent UFD: pbms_delete_all_blobs_in_table(database);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_drop_table_blobs(&lt;span style="color:#760f50;"&gt;struct&lt;/span&gt; st_mysql *mysql, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *database, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *table);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * pbms_table_renamed() &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * This function is called after a table containing blobs has been renamed.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; *&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Equivalent UFD: pbms_rename_table_with_blobs(database);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_table_renamed(&lt;span style="color:#760f50;"&gt;struct&lt;/span&gt; st_mysql *mysql, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *database, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *old_table, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *new_table);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * pbms_dropping_database() &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Call this function before dropping any database that contained tables containing blobs. This gives the PBMS&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * engine a chance to remove it's files and sub directories from the database directory so that it can be&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * deleted.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; *&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; * Equivalent UFD: pbms_dropping_database(database);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt; */&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;pbms_bool pbms_dropping_database(&lt;span style="color:#760f50;"&gt;struct&lt;/span&gt; st_mysql *mysql, &lt;span style="color:#760f50;"&gt;const&lt;/span&gt; &lt;span style="color:#760f50;"&gt;char&lt;/span&gt; *database);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;/*&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;User defined functions provided with the PBMS engine:&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;//UDFs &lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;used in triggers: &lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;// 'col_position' is the ordinal of the longblob column starting at position 1.&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_insert_blob_trig(database, table col_position, blob_url);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_update_blob_trig(database, table col_position, old_blob_url, new_blob_url);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_delete_blob_trig(database, table col_position, blob_url);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;// Example:&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;crete table x.foo(c1 int, c2 longblob);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;create trigger x.foo_insert_trig  BEFORE INSERT on x.foo for each row BEGIN set NEW.c2 = pbms_insert_blob_trig("x", "foo", 2, NEW.c2); END&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;create trigger x.foo_update_trig  BEFORE UPDATE on x.foo for each row BEGIN set NEW.c2 = pbms_update_blob_trig("x", "foo", 2, OLD.c2, NEW.c2); END&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;create trigger x.foo_delete_trig  BEFORE UPDATE on x.foo for each row BEGIN declare dummy integer; set dummy = pbms_delete_blob_trig("x", "foo", 2, OLD.c2); END&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;///////////&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_delete_all_blobs_in_table(database, table);&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_rename_table_with_blobs(database, old_table, new_table);&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_dropping_database(database);&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;pbms_enabled_engine(engine);&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25; min-height: 14.0px"&gt;NOTE: pbms_enabled_engine() returns -1 on error.&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_insert_blob_trig RETURNS STRING SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_update_blob_trig RETURNS STRING SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_delete_blob_trig RETURNS INTEGER SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_delete_all_blobs_in_table RETURNS INTEGER SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_rename_table_with_blobs RETURNS INTEGER SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_dropping_database RETURNS INTEGER SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;CREATE FUNCTION pbms_enabled_engine RETURNS INTEGER SONAME "libpbms.so";&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;*/&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #236e25"&gt;&lt;/p&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;Use of  PBMS with non PBMS enabled engines is not yet transactionally safe. This means that if you use it on an INODB table while say doing some inserts in a transaction and then rollback the transaction the blob references will remain. Of course PBMS enabled engines such as PBXT do not have this problem. Making PBMS transactionally safe with non PBMS enabled engines is on my to-do list.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;The test shell 'pbmstest' included with the PBMS source uses the new API functions and by default performs it's tests using a MYISAM table. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;I am currently working on getting the documentation updated with the new features and name change so that I can make an official release with this version.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;Until then I invite anyone interested to grab a copy of the latest code from launchpad and play with it.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;Barry&lt;/span&gt;&lt;/span&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 0, 51);"&gt;&lt;/span&gt;&lt;/p&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-6290598891370578718?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/6290598891370578718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=6290598891370578718' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6290598891370578718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6290598891370578718'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/10/primebase-pbms-does-myisam.html' title='PrimeBase PBMS does MYISAM'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-6571706613749834333</id><published>2008-09-18T11:15:00.000-07:00</published><updated>2008-09-18T11:48:45.359-07:00</updated><title type='text'>BLOB streaming has changed its name and home</title><content type='html'>Hi all,&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So you may have been thinking that maybe calling something "&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;MyBS&lt;/span&gt;" was not such a great marketing idea. Even as a developer I have to admit that it isn't the best name abbreviation to have. So we decided to change it. We considered calling it the "BLOB Streaming Engine" but that resulted in the abbreviation "&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;BSE"&lt;/span&gt; which also isn't so great. What we have finally settled on is the "PrimeBase Media Stream" engine or "&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PBMS&lt;/span&gt;" which I think is fairly safe.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We have also relocated the source for &lt;span class="Apple-style-span" style="font-weight: bold; "&gt;PBMS &lt;/span&gt;from sourceforge  onto LaunchPad where you can find it at: &lt;a href="https://code.launchpad.net/pbms"&gt;https://code.launchpad.net/pbms&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-6571706613749834333?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/6571706613749834333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=6571706613749834333' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6571706613749834333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/6571706613749834333'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/09/blob-streaming-has-changed-its-name-and.html' title='BLOB streaming has changed its name and home'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5313622847232042654.post-5773586364975841840</id><published>2008-09-10T09:33:00.000-07:00</published><updated>2008-09-10T09:56:08.716-07:00</updated><title type='text'>Alpha release v05.05 of the BLOB Streaming Engine</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Alpha version 5.05 of the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;a href="http://www.blobstreaming.org"&gt;BLOB streaming engine for MySQL&lt;/a&gt;&lt;/span&gt;  has been released. You can download the source code from &lt;a href="http://www.blobstreaming.org/download"&gt;www.blobstreaming.org/download&lt;/a&gt;. The documentation has also been updated .&lt;div&gt;&lt;br /&gt;What's new in 5.05:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A 'C' API has been added for client applications. It provides all the basic functions needed to connect to the BLOB streaming engine and upload and download BLOBs efficiently.&lt;/li&gt;&lt;li&gt;A test client application has been added to the project to demonstrate the use of the new API.&lt;/li&gt;&lt;li&gt;Added discover table support for the engine's system tables.&lt;/li&gt;&lt;li&gt;Simplified the configuration: To configure the engine all you have to do is provide the path to the MySQL source tree (after building MySQL). All build options are taken from the MySQL build.&lt;/li&gt;&lt;li&gt;And of course there are assorted bug fixes, details of which are listed in the Changelog.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of interest to other engine developers may be the way that I implemented 'discover tables'. I have created a very generic function that takes a structure similar to that used by schema plug-ins and generates the required 'frm' file. Implementation is contained in the file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;BSDiscover.cc&lt;/span&gt; and you can see how it is used in &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;ha_mybs.cc&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5313622847232042654-5773586364975841840?l=bpbdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bpbdev.blogspot.com/feeds/5773586364975841840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5313622847232042654&amp;postID=5773586364975841840' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5773586364975841840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5313622847232042654/posts/default/5773586364975841840'/><link rel='alternate' type='text/html' href='http://bpbdev.blogspot.com/2008/09/alpha-release-v0505-of-blob-streaming.html' title='Alpha release v05.05 of the BLOB Streaming Engine'/><author><name>Barry Leslie</name><uri>http://www.blogger.com/profile/17401344028762041511</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_ESrUDY1Mluc/SL7XPNB4d9I/AAAAAAAAAAo/2v5QFuB-oY0/s1600-R/bl.jpg'/></author><thr:total>0</thr:total></entry></feed>
