List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:September 4 2009 11:34am
Subject:bzr commit into mysql-5.1-telco-7.0 branch (jonas:2984)
View as plain text  
#At file:///home/jonas/src/telco-6.4/ based on revid:frazer@stripped

 2984 Jonas Oreland	2009-09-04 [merge]
      merge 63 to 70

    modified:
      sql/ha_ndbcluster.cc
      storage/ndb/include/kernel/AttributeHeader.hpp
      storage/ndb/include/ndbapi/NdbDictionary.hpp
      storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
      storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
      storage/ndb/tools/desc.cpp
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-09-03 09:54:52 +0000
+++ b/sql/ha_ndbcluster.cc	2009-09-04 11:33:38 +0000
@@ -7905,7 +7905,9 @@ void ha_ndbcluster::get_auto_increment(u
     Ndb_tuple_id_range_guard g(m_share);
     if (m_skip_auto_increment &&
         ndb->readAutoIncrementValue(m_table, g.range, auto_value) ||
-        ndb->getAutoIncrementValue(m_table, g.range, auto_value, m_autoincrement_prefetch, increment, offset))
+        ndb->getAutoIncrementValue(m_table, g.range, auto_value, 
+                                   Uint32(m_autoincrement_prefetch), 
+                                   increment, offset))
     {
       if (--retries && !thd->killed &&
           ndb->getNdbError().status == NdbError::TemporaryError)

=== modified file 'storage/ndb/include/kernel/AttributeHeader.hpp'
--- a/storage/ndb/include/kernel/AttributeHeader.hpp	2009-05-27 12:11:46 +0000
+++ b/storage/ndb/include/kernel/AttributeHeader.hpp	2009-09-04 11:01:23 +0000
@@ -53,7 +53,13 @@ public:
   STATIC_CONST( COPY_ROWID   = 0xFFF1 );
   STATIC_CONST( READ_ALL     = 0xFFF0 );
   STATIC_CONST( READ_LCP     = 0xFFEF );
+
+  // Extents * sizeof(Extent) allocated to fragment
+  STATIC_CONST( FRAGMENT_EXTENT_SPACE = 0xFFEC );
   
+  // Free but allocated DD extent space
+  STATIC_CONST( FRAGMENT_FREE_EXTENT_SPACE = 0xFFEB );
+
   /**
    * Optimize pseudo column and optimization options
    */

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	2009-06-13 19:09:35 +0000
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	2009-09-04 11:33:38 +0000
@@ -584,7 +584,9 @@ public:
     static const Column * ANY_VALUE;
     static const Column * COPY_ROWID;
     static const Column * OPTIMIZE;
-    
+    static const Column * FRAGMENT_EXTENT_SPACE;
+    static const Column * FRAGMENT_FREE_EXTENT_SPACE;
+
     int getSizeInBytes() const;
 
     int getBlobVersion() const; // NDB_BLOB_V1 or NDB_BLOB_V2

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2009-08-04 10:02:49 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2009-09-04 11:33:38 +0000
@@ -575,9 +575,9 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
     Local_key m_key;
     Uint32 m_frag_ptr_i;
     Uint32 m_extent_info_ptr;
-    Uint16 m_estimated_free_space; // in bytes/records
-    Uint16 m_list_index;           // in Disk_alloc_info.m_page_requests
-    Uint16 m_ref_count;            // Waiters for page
+    Uint16 m_original_estimated_free_space; // in bytes/records
+    Uint16 m_list_index;                  // in Disk_alloc_info.m_page_requests
+    Uint16 m_ref_count;                   // Waiters for page
     Uint16 m_uncommitted_used_space;
     Uint32 nextList;
     Uint32 prevList;
@@ -3163,9 +3163,21 @@ private:
   void drop_table_logsync_callback(Signal*, Uint32, Uint32);
 
   void disk_page_set_dirty(Ptr<Page>);
-  void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
-  void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>);
-  
+  void restart_setup_page(Disk_alloc_info&, Ptr<Page>, Int32 estimate);
+  void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>, Int32 delta);
+
+  void disk_page_move_page_request(Disk_alloc_info& alloc,
+                                   Ptr<Extent_info>,
+                                   Ptr<Page_request> req,
+                                   Uint32 old_idx, Uint32 new_idx);
+
+  void disk_page_move_dirty_page(Disk_alloc_info& alloc,
+                                 Ptr<Extent_info> extentPtr,
+                                 Ptr<Page> pagePtr,
+                                 Uint32 old_idx, Uint32 new_idx);
+
+  void disk_page_get_allocated(const Tablerec*, const Fragrecord*,
+                               Uint64 res[2]);
   /**
    * Disk restart code
    */

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp	2009-05-28 13:12:22 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp	2009-09-04 11:33:38 +0000
@@ -40,7 +40,7 @@ operator<<(NdbOut& out, const Ptr<Dbtup:
 {
   out << "[ Page_request: ptr.i: " << ptr.i
       << " " << ptr.p->m_key
-      << " m_estimated_free_space: " << ptr.p->m_estimated_free_space
+      << " m_original_estimated_free_space: " << ptr.p->m_original_estimated_free_space
       << " m_list_index: " << ptr.p->m_list_index
       << " m_frag_ptr_i: " << ptr.p->m_frag_ptr_i
       << " m_extent_info_ptr: " << ptr.p->m_extent_info_ptr
@@ -248,16 +248,41 @@ Dbtup::Disk_alloc_info::calc_extent_pos(
 
 void
 Dbtup::update_extent_pos(Disk_alloc_info& alloc, 
-			 Ptr<Extent_info> extentPtr)
+                         Ptr<Extent_info> extentPtr,
+                         Int32 delta)
 {
+  if (delta < 0)
+  {
+    jam();
+    Uint32 sub = Uint32(- delta);
+    ddassert(extentPtr.p->m_free_space >= sub);
+    extentPtr.p->m_free_space -= sub;
+  }
+  else
+  {
+    jam();
+    extentPtr.p->m_free_space += delta;
+    ndbassert(Uint32(delta) <= alloc.calc_page_free_space(0));
+  }
+
 #ifdef VM_TRACE
-  Uint32 min_free = 0;
+  Uint32 cnt = 0;
+  Uint32 sum = 0;
   for(Uint32 i = 0; i<MAX_FREE_LIST; i++)
   {
-    Uint32 sum = alloc.calc_page_free_space(i);
-    min_free += sum * extentPtr.p->m_free_page_count[i];
+    cnt += extentPtr.p->m_free_page_count[i];
+    sum += extentPtr.p->m_free_page_count[i] * alloc.calc_page_free_space(i);
   }
-  ddassert(extentPtr.p->m_free_space >= min_free);
+  if (extentPtr.p->m_free_page_count[0] == cnt)
+  {
+    ddassert(extentPtr.p->m_free_space == cnt*alloc.m_page_free_bits_map[0]);
+  }
+  else
+  {
+    ddassert(extentPtr.p->m_free_space < cnt*alloc.m_page_free_bits_map[0]);
+  }
+  ddassert(extentPtr.p->m_free_space >= sum);
+  ddassert(extentPtr.p->m_free_space <= cnt*alloc.m_page_free_bits_map[0]);
 #endif
   
   Uint32 old = extentPtr.p->m_free_matrix_pos;
@@ -281,7 +306,8 @@ Dbtup::update_extent_pos(Disk_alloc_info
 }
 
 void
-Dbtup::restart_setup_page(Disk_alloc_info& alloc, PagePtr pagePtr)
+Dbtup::restart_setup_page(Disk_alloc_info& alloc, PagePtr pagePtr,
+                          Int32 estimate)
 {
   jam();
   /**
@@ -297,16 +323,24 @@ Dbtup::restart_setup_page(Disk_alloc_inf
   ndbrequire(c_extent_hash.find(extentPtr, key));
   pagePtr.p->m_extent_info_ptr = extentPtr.i;
 
-  Uint32 idx = pagePtr.p->list_index & ~0x8000;
-  Uint32 estimated = alloc.calc_page_free_space(idx);
   Uint32 real_free = pagePtr.p->free_space;
-
-  ddassert(real_free >= estimated);
-  if (real_free != estimated)
+  const bool prealloc = estimate >= 0;
+  Uint32 estimated;
+  if (prealloc)
   {
     jam();
-    extentPtr.p->m_free_space += (real_free - estimated);
-    update_extent_pos(alloc, extentPtr);
+    /**
+     * If this is during prealloc, use estimate from there
+     */
+    estimated = (Uint32)estimate;
+  }
+  else
+  {
+    jam();
+    /**
+     * else use the estimate based on the actual free space
+     */
+    estimated =alloc.calc_page_free_space(alloc.calc_page_free_bits(real_free));
   }
 
 #ifdef VM_TRACE
@@ -323,10 +357,30 @@ Dbtup::restart_setup_page(Disk_alloc_inf
     (void) tsman.get_page_free_bits(&page, &uncommitted, &committed);
     jamEntry();
     
-    idx = alloc.calc_page_free_bits(real_free);
-    ddassert(idx == committed);
+    ddassert(alloc.calc_page_free_bits(real_free) == committed);
+    if (prealloc)
+    {
+      /**
+       * tsman.alloc_page sets the uncommitted-bits to MAX_FREE_LIST -1
+       *   to avoid page being preallocated several times
+       */
+      ddassert(uncommitted == MAX_FREE_LIST - 1);
+    }
+    else
+    {
+      ddassert(committed == uncommitted);
+    }
   }
 #endif
+
+  ddassert(real_free >= estimated);
+
+  if (real_free != estimated)
+  {
+    jam();
+    Uint32 delta = (real_free-estimated);
+    update_extent_pos(alloc, extentPtr, delta);
+  }
 }
 
 /**
@@ -524,6 +578,7 @@ Dbtup::disk_page_prealloc(Signal* signal
 	  
 	  Logfile_client lgman(this, c_lgman, logfile_group_id);
 	  int res= lgman.get_log_buffer(signal, sz, &cb);
+          jamEntry();
 	  switch(res){
 	  case 0:
 	    break;
@@ -575,9 +630,9 @@ Dbtup::disk_page_prealloc(Signal* signal
   Uint32 size= alloc.calc_page_free_space((Uint32)pageBits);
   
   ddassert(size >= sz);
-  Uint32 new_size = size - sz;   // Subtract alloc rec
-  req.p->m_estimated_free_space= new_size; // Store on page request
+  req.p->m_original_estimated_free_space = size;
 
+  Uint32 new_size = size - sz;   // Subtract alloc rec
   Uint32 newPageBits= alloc.calc_page_free_bits(new_size);
   if (newPageBits != (Uint32)pageBits)
   {
@@ -586,9 +641,8 @@ Dbtup::disk_page_prealloc(Signal* signal
     ext.p->m_free_page_count[pageBits]--;
     ext.p->m_free_page_count[newPageBits]++;
   }
-  ddassert(ext.p->m_free_space >= sz);
-  ext.p->m_free_space -= sz;
-  
+  update_extent_pos(alloc, ext, -sz);
+
   // And put page request in correct free list
   idx= alloc.calc_page_free_bits(new_size);
   {
@@ -653,26 +707,15 @@ Dbtup::disk_page_prealloc_dirty_page(Dis
   c_extent_pool.getPtr(extentPtr, ext);
 
   Uint32 new_idx= alloc.calc_page_free_bits(free - used);
-  ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
 
   if (old_idx != new_idx)
   {
     jam();
-    LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
-    LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
-    old_list.remove(pagePtr);
-    new_list.add(pagePtr);
-
-    ddassert(extentPtr.p->m_free_page_count[old_idx]);
-    extentPtr.p->m_free_page_count[old_idx]--;
-    extentPtr.p->m_free_page_count[new_idx]++;
-    pagePtr.p->list_index= new_idx;  
+    disk_page_move_dirty_page(alloc, extentPtr, pagePtr, old_idx, new_idx);
   }
 
   pagePtr.p->uncommitted_used_space = used;
-  ddassert(extentPtr.p->m_free_space >= sz);
-  extentPtr.p->m_free_space -= sz;
-  update_extent_pos(alloc, extentPtr);
+  update_extent_pos(alloc, extentPtr, -sz);
 }
 
 
@@ -684,39 +727,26 @@ Dbtup::disk_page_prealloc_transit_page(D
   jam();
   ddassert(req.p->m_list_index == old_idx);
 
-  Uint32 free= req.p->m_estimated_free_space;
+  Uint32 free= req.p->m_original_estimated_free_space;
   Uint32 used= req.p->m_uncommitted_used_space + sz;
   Uint32 ext= req.p->m_extent_info_ptr;
   
   Ptr<Extent_info> extentPtr;
   c_extent_pool.getPtr(extentPtr, ext);
 
-  ddassert(free >= sz);
-  Uint32 new_idx= alloc.calc_page_free_bits(free - sz);
+  ddassert(free >= used);
+  Uint32 new_idx= alloc.calc_page_free_bits(free - used);
   
   if (old_idx != new_idx)
   {
     jam();
-    Page_request_list::Head *lists = alloc.m_page_requests;
-    Local_page_request_list old_list(c_page_request_pool, lists[old_idx]);
-    Local_page_request_list new_list(c_page_request_pool, lists[new_idx]);
-    old_list.remove(req);
-    new_list.add(req);
-
-    ddassert(extentPtr.p->m_free_page_count[old_idx]);
-    extentPtr.p->m_free_page_count[old_idx]--;
-    extentPtr.p->m_free_page_count[new_idx]++;
-    req.p->m_list_index= new_idx;  
+    disk_page_move_page_request(alloc, extentPtr, req, old_idx, new_idx);
   }
 
   req.p->m_uncommitted_used_space = used;
-  req.p->m_estimated_free_space = free - sz;
-  ddassert(extentPtr.p->m_free_space >= sz);
-  extentPtr.p->m_free_space -= sz;
-  update_extent_pos(alloc, extentPtr);
+  update_extent_pos(alloc, extentPtr, -sz);
 }
 
-
 void
 Dbtup::disk_page_prealloc_callback(Signal* signal, 
 				   Uint32 page_request, Uint32 page_id)
@@ -738,13 +768,88 @@ Dbtup::disk_page_prealloc_callback(Signa
   pagePtr.i = gpage.i;
   pagePtr.p = reinterpret_cast<Page*>(gpage.p);
 
+  Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
   if (unlikely(pagePtr.p->m_restart_seq != globalData.m_restart_seq))
   {
+    jam();
     D(V(pagePtr.p->m_restart_seq) << V(globalData.m_restart_seq));
-    restart_setup_page(fragPtr.p->m_disk_alloc_info, pagePtr);
+    restart_setup_page(alloc, pagePtr, req.p->m_original_estimated_free_space);
+  }
+
+  Ptr<Extent_info> extentPtr;
+  c_extent_pool.getPtr(extentPtr, req.p->m_extent_info_ptr);
+
+  pagePtr.p->uncommitted_used_space += req.p->m_uncommitted_used_space;
+  ddassert(pagePtr.p->free_space >= pagePtr.p->uncommitted_used_space);
+
+  Uint32 free = pagePtr.p->free_space - pagePtr.p->uncommitted_used_space;
+  Uint32 idx = req.p->m_list_index;
+  Uint32 real_idx = alloc.calc_page_free_bits(free);
+
+  if (idx != real_idx)
+  {
+    jam();
+    ddassert(extentPtr.p->m_free_page_count[idx]);
+    extentPtr.p->m_free_page_count[idx]--;
+    extentPtr.p->m_free_page_count[real_idx]++;
+    update_extent_pos(alloc, extentPtr, 0);
+  }
+
+  {
+    /**
+     * add to dirty list
+     */
+    pagePtr.p->list_index = real_idx;
+    ArrayPool<Page> *cheat_pool= (ArrayPool<Page>*)&m_global_page_pool;
+    LocalDLList<Page> list(* cheat_pool, alloc.m_dirty_pages[real_idx]);
+    list.add(pagePtr);
+  }
+
+  {
+    /**
+     * release page request
+     */
+    Local_page_request_list list(c_page_request_pool,
+				 alloc.m_page_requests[idx]);
+    list.release(req);
   }
+}
+
+void
+Dbtup::disk_page_move_dirty_page(Disk_alloc_info& alloc,
+                                 Ptr<Extent_info> extentPtr,
+                                 Ptr<Page> pagePtr,
+                                 Uint32 old_idx,
+                                 Uint32 new_idx)
+{
+  ddassert(extentPtr.p->m_free_page_count[old_idx]);
+  extentPtr.p->m_free_page_count[old_idx]--;
+  extentPtr.p->m_free_page_count[new_idx]++;
+
+  ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
+  LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
+  LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
+  old_list.remove(pagePtr);
+  new_list.add(pagePtr);
+  pagePtr.p->list_index = new_idx;
+}
 
-  disk_page_prealloc_callback_common(signal, req, fragPtr, pagePtr);
+void
+Dbtup::disk_page_move_page_request(Disk_alloc_info& alloc,
+                                   Ptr<Extent_info> extentPtr,
+                                   Ptr<Page_request> req,
+                                   Uint32 old_idx, Uint32 new_idx)
+{
+  Page_request_list::Head *lists = alloc.m_page_requests;
+  Local_page_request_list old_list(c_page_request_pool, lists[old_idx]);
+  Local_page_request_list new_list(c_page_request_pool, lists[new_idx]);
+  old_list.remove(req);
+  new_list.add(req);
+
+  ddassert(extentPtr.p->m_free_page_count[old_idx]);
+  extentPtr.p->m_free_page_count[old_idx]--;
+  extentPtr.p->m_free_page_count[new_idx]++;
+  req.p->m_list_index= new_idx;
 }
 
 void
@@ -781,17 +886,6 @@ Dbtup::disk_page_prealloc_initial_callba
   Ptr<Extent_info> extentPtr;
   c_extent_pool.getPtr(extentPtr, req.p->m_extent_info_ptr);
 
-  pagePtr.p->m_page_no= req.p->m_key.m_page_no;
-  pagePtr.p->m_file_no= req.p->m_key.m_file_no;
-  pagePtr.p->m_table_id= fragPtr.p->fragTableId;
-  pagePtr.p->m_fragment_id = fragPtr.p->fragmentId;
-  pagePtr.p->m_extent_no = extentPtr.p->m_key.m_page_idx; // logical extent no
-  pagePtr.p->m_extent_info_ptr= req.p->m_extent_info_ptr;
-  pagePtr.p->m_restart_seq = globalData.m_restart_seq;
-  pagePtr.p->list_index = 0x8000;
-  pagePtr.p->uncommitted_used_space = 0;
-  pagePtr.p->nextList = pagePtr.p->prevList = RNIL;
-  
   if (tabPtr.p->m_attributes[DD].m_no_of_varsize == 0)
   {
     convertThPage((Fix_page*)pagePtr.p, tabPtr.p, DD);
@@ -800,70 +894,42 @@ Dbtup::disk_page_prealloc_initial_callba
   {
     abort();
   }
-  disk_page_prealloc_callback_common(signal, req, fragPtr, pagePtr);
-}
 
-void
-Dbtup::disk_page_prealloc_callback_common(Signal* signal, 
-					  Ptr<Page_request> req, 
-					  Ptr<Fragrecord> fragPtr, 
-					  PagePtr pagePtr)
-{
-  /**
-   * 1) remove page request from Disk_alloc_info.m_page_requests
-   * 2) Add page to Disk_alloc_info.m_dirty_pages
-   * 3) register callback in pgman (unmap callback)
-   * 4) inform pgman about current users
-   */
-  Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
-  ddassert((pagePtr.p->list_index & 0x8000) == 0x8000);
-  ddassert(pagePtr.p->m_extent_info_ptr == req.p->m_extent_info_ptr);
-  ddassert(pagePtr.p->m_page_no == req.p->m_key.m_page_no);
-  ddassert(pagePtr.p->m_file_no == req.p->m_key.m_file_no);
-  
-  Uint32 old_idx = req.p->m_list_index;
-  Uint32 free= req.p->m_estimated_free_space;
-  Uint32 ext = req.p->m_extent_info_ptr;
-  Uint32 used= req.p->m_uncommitted_used_space;
-  Uint32 real_free = pagePtr.p->free_space;
-  Uint32 real_used = used + pagePtr.p->uncommitted_used_space;
- 
-  ddassert(real_free >= free);
-  ddassert(real_free >= real_used);
-  ddassert(alloc.calc_page_free_bits(free) == old_idx);
-  Uint32 new_idx= alloc.calc_page_free_bits(real_free - real_used);
+  pagePtr.p->m_page_no= req.p->m_key.m_page_no;
+  pagePtr.p->m_file_no= req.p->m_key.m_file_no;
+  pagePtr.p->m_table_id= fragPtr.p->fragTableId;
+  pagePtr.p->m_fragment_id = fragPtr.p->fragmentId;
+  pagePtr.p->m_extent_no = extentPtr.p->m_key.m_page_idx; // logical extent no
+  pagePtr.p->m_extent_info_ptr= req.p->m_extent_info_ptr;
+  pagePtr.p->m_restart_seq = globalData.m_restart_seq;
+  pagePtr.p->nextList = pagePtr.p->prevList = RNIL;
+  pagePtr.p->list_index = req.p->m_list_index;
+  pagePtr.p->uncommitted_used_space = req.p->m_uncommitted_used_space;
 
-  /**
-   * Add to dirty pages
-   */
-  ArrayPool<Page> *cheat_pool= (ArrayPool<Page>*)&m_global_page_pool;
-  LocalDLList<Page> list(* cheat_pool, alloc.m_dirty_pages[new_idx]);
-  list.add(pagePtr);
-  pagePtr.p->uncommitted_used_space = real_used;
-  pagePtr.p->list_index = new_idx;
+  Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
+  Uint32 idx = req.p->m_list_index;
 
-  if (old_idx != new_idx || free != real_free)
   {
-    jam();
-    Ptr<Extent_info> extentPtr;
-    c_extent_pool.getPtr(extentPtr, ext);
+    Uint32 free = pagePtr.p->free_space - pagePtr.p->uncommitted_used_space;
+    ddassert(idx == alloc.calc_page_free_bits(free));
+    ddassert(pagePtr.p->free_space == req.p->m_original_estimated_free_space);
+  }
 
-    extentPtr.p->m_free_space += (real_free - free);
-    
-    if (old_idx != new_idx)
-    {
-      jam();
-      ddassert(extentPtr.p->m_free_page_count[old_idx]);
-      extentPtr.p->m_free_page_count[old_idx]--;
-      extentPtr.p->m_free_page_count[new_idx]++;
-    }
-    
-    update_extent_pos(alloc, extentPtr);
+  {
+    /**
+     * add to dirty list
+     */
+    ArrayPool<Page> *cheat_pool= (ArrayPool<Page>*)&m_global_page_pool;
+    LocalDLList<Page> list(* cheat_pool, alloc.m_dirty_pages[idx]);
+    list.add(pagePtr);
   }
-  
+
   {
+    /**
+     * release page request
+     */
     Local_page_request_list list(c_page_request_pool, 
-				 alloc.m_page_requests[old_idx]);
+				 alloc.m_page_requests[idx]);
     list.release(req);
   }
 }
@@ -873,7 +939,8 @@ Dbtup::disk_page_set_dirty(PagePtr pageP
 {
   jam();
   Uint32 idx = pagePtr.p->list_index;
-  if ((idx & 0x8000) == 0)
+  if ((pagePtr.p->m_restart_seq == globalData.m_restart_seq) &&
+      ((idx & 0x8000) == 0))
   {
     jam();
     /**
@@ -904,13 +971,16 @@ Dbtup::disk_page_set_dirty(PagePtr pageP
   Uint32 used = pagePtr.p->uncommitted_used_space;
   if (unlikely(pagePtr.p->m_restart_seq != globalData.m_restart_seq))
   {
+    jam();
     D(V(pagePtr.p->m_restart_seq) << V(globalData.m_restart_seq));
-    restart_setup_page(alloc, pagePtr);
+    restart_setup_page(alloc, pagePtr, -1);
+    ndbassert(free == pagePtr.p->free_space);
     idx = alloc.calc_page_free_bits(free);
     used = 0;
   }
   else
   {
+    jam();
     idx &= ~0x8000;
     ddassert(idx == alloc.calc_page_free_bits(free - used));
   }
@@ -1139,20 +1209,10 @@ Dbtup::disk_page_free(Signal *signal, 
   if (old_idx != new_idx)
   {
     jam();
-    ddassert(extentPtr.p->m_free_page_count[old_idx]);
-    extentPtr.p->m_free_page_count[old_idx]--;
-    extentPtr.p->m_free_page_count[new_idx]++;
-
-    ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
-    LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
-    LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
-    old_list.remove(pagePtr);
-    new_list.add(pagePtr);
-    pagePtr.p->list_index = new_idx;
+    disk_page_move_dirty_page(alloc, extentPtr, pagePtr, old_idx, new_idx);
   }
   
-  extentPtr.p->m_free_space += sz;
-  update_extent_pos(alloc, extentPtr);
+  update_extent_pos(alloc, extentPtr, sz);
 #if NOT_YET_FREE_EXTENT
   if (check_free(extentPtr.p) == 0)
   {
@@ -1166,6 +1226,7 @@ Dbtup::disk_page_abort_prealloc(Signal *
 				Local_key* key, Uint32 sz)
 {
   jam();
+
   Page_cache_client::Request req;
   req.m_callback.m_callbackData= sz;
   req.m_callback.m_callbackFunction = 
@@ -1231,47 +1292,29 @@ Dbtup::disk_page_abort_prealloc_callback
   disk_page_set_dirty(pagePtr);
 
   Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
-  Uint32 page_idx = pagePtr.p->list_index;
+
+  Ptr<Extent_info> extentPtr;
+  c_extent_pool.getPtr(extentPtr, pagePtr.p->m_extent_info_ptr);
+
+  Uint32 idx = pagePtr.p->list_index & 0x7FFF;
   Uint32 used = pagePtr.p->uncommitted_used_space;
   Uint32 free = pagePtr.p->free_space;
-  Uint32 ext = pagePtr.p->m_extent_info_ptr;
 
-  Uint32 old_idx = page_idx & 0x7FFF;
   ddassert(free >= used);
   ddassert(used >= sz);
-  ddassert(alloc.calc_page_free_bits(free - used) == old_idx);
+  ddassert(alloc.calc_page_free_bits(free - used) == idx);
+
+  pagePtr.p->uncommitted_used_space = used - sz;
+
   Uint32 new_idx = alloc.calc_page_free_bits(free - used + sz);
 
-  Ptr<Extent_info> extentPtr;
-  c_extent_pool.getPtr(extentPtr, ext);
-  if (old_idx != new_idx)
+  if (idx != new_idx)
   {
     jam();
-    ddassert(extentPtr.p->m_free_page_count[old_idx]);
-    extentPtr.p->m_free_page_count[old_idx]--;
-    extentPtr.p->m_free_page_count[new_idx]++;
-
-    if (old_idx == page_idx)
-    {
-      jam();
-      ArrayPool<Page> *pool= (ArrayPool<Page>*)&m_global_page_pool;
-      LocalDLList<Page> old_list(*pool, alloc.m_dirty_pages[old_idx]);
-      LocalDLList<Page> new_list(*pool, alloc.m_dirty_pages[new_idx]);
-      old_list.remove(pagePtr);
-      new_list.add(pagePtr);
-      pagePtr.p->list_index = new_idx;
-    }
-    else
-    {
-      jam();
-      pagePtr.p->list_index = new_idx | 0x8000;
-    }
+    disk_page_move_dirty_page(alloc, extentPtr, pagePtr, idx, new_idx);
   }
   
-  pagePtr.p->uncommitted_used_space = used - sz;
-
-  extentPtr.p->m_free_space += sz;
-  update_extent_pos(alloc, extentPtr);
+  update_extent_pos(alloc, extentPtr, sz);
 #if NOT_YET_FREE_EXTENT
   if (check_free(extentPtr.p) == 0)
   {
@@ -1333,6 +1376,7 @@ Dbtup::disk_page_undo_alloc(Page* page, 
   Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } };
   
   Uint64 lsn= lgman.add_entry(c, 1);
+  jamEntry();
   Page_cache_client pgman(this, c_pgman);
   pgman.update_lsn(* key, lsn);
   jamEntry();
@@ -1366,6 +1410,7 @@ Dbtup::disk_page_undo_update(Page* page,
   ndbassert(4*(3 + sz + 1) == (sizeof(update) + 4*sz - 4));
     
   Uint64 lsn= lgman.add_entry(c, 3);
+  jamEntry();
   Page_cache_client pgman(this, c_pgman);
   pgman.update_lsn(* key, lsn);
   jamEntry();
@@ -1399,6 +1444,7 @@ Dbtup::disk_page_undo_free(Page* page, c
   ndbassert(4*(3 + sz + 1) == (sizeof(free) + 4*sz - 4));
   
   Uint64 lsn= lgman.add_entry(c, 3);
+  jamEntry();
   Page_cache_client pgman(this, c_pgman);
   pgman.update_lsn(* key, lsn);
   jamEntry();
@@ -1903,7 +1949,7 @@ Dbtup::disk_restart_alloc_extent(Uint32 
 
 void
 Dbtup::disk_restart_page_bits(Uint32 tableId, Uint32 fragId,
-			      const Local_key*, Uint32 bits)
+			      const Local_key* key, Uint32 bits)
 {
   jam();
   TablerecPtr tabPtr;
@@ -1918,7 +1964,35 @@ Dbtup::disk_restart_page_bits(Uint32 tab
   
   Uint32 size= alloc.calc_page_free_space(bits);  
   
-  ext.p->m_free_space += size;
   ext.p->m_free_page_count[bits]++;
+  update_extent_pos(alloc, ext, size); // actually only to update free_space
   ndbassert(ext.p->m_free_matrix_pos == RNIL);
 }
+
+void
+Dbtup::disk_page_get_allocated(const Tablerec* tabPtrP,
+                               const Fragrecord * fragPtrP,
+                               Uint64 res[2])
+{
+  res[0] = res[1] = 0;
+  if (tabPtrP->m_no_of_disk_attributes)
+  {
+    jam();
+    const Disk_alloc_info& alloc= fragPtrP->m_disk_alloc_info;
+    Uint64 cnt = 0;
+    Uint64 free = 0;
+
+    {
+      Disk_alloc_info& tmp = const_cast<Disk_alloc_info&>(alloc);
+      Local_fragment_extent_list list(c_extent_pool, tmp.m_extent_list);
+      Ptr<Extent_info> extentPtr;
+      for (list.first(extentPtr); !extentPtr.isNull(); list.next(extentPtr))
+      {
+        cnt++;
+        free += extentPtr.p->m_free_space;
+      }
+    }
+    res[0] = cnt * alloc.m_extent_size * File_formats::NDB_PAGE_SIZE;
+    res[1] = free * 4 * tabPtrP->m_offsets[DD].m_fix_header_size;
+  }
+}

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp	2009-09-04 11:33:38 +0000
@@ -354,11 +354,14 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* 
       Logfile_client lgman(this, c_lgman, regFragPtr.p->m_logfile_group_id);
       if((terrorCode = lgman.alloc_log_space(sz)))
       {
+        jamEntry();
         addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
         return;
       }
       
+      jamEntry();
       int res= lgman.get_log_buffer(signal, sz, &cb);
+      jamEntry();
       switch(res){
       case 0:
         jam();
@@ -1323,12 +1326,14 @@ Dbtup::undo_createtable_callback(Signal*
   Logfile_client::Change c[1] = {{ &create, sizeof(create) >> 2 } };
   
   Uint64 lsn= lgman.add_entry(c, 1);
+  jamEntry();
 
   Logfile_client::Request req;
   req.m_callback.m_callbackData= fragOperPtr.i;
   req.m_callback.m_callbackIndex = UNDO_CREATETABLE_LOGSYNC_CALLBACK;
   
   int ret = lgman.sync_lsn(signal, lsn, &req, 0);
+  jamEntry();
   switch(ret){
   case 0:
     return;
@@ -1625,6 +1630,7 @@ void Dbtup::releaseFragment(Signal* sign
     D("Logfile_client - releaseFragment");
     Logfile_client lgman(this, c_lgman, logfile_group_id);
     int r0 = lgman.alloc_log_space(sz);
+    jamEntry();
     if (r0)
     {
       jam();
@@ -1634,6 +1640,7 @@ void Dbtup::releaseFragment(Signal* sign
     }
 
     int res= lgman.get_log_buffer(signal, sz, &cb);
+    jamEntry();
     switch(res){
     case 0:
       jam();
@@ -1642,6 +1649,7 @@ void Dbtup::releaseFragment(Signal* sign
       warningEvent("Failed to get log buffer for drop table: %u",
 		   tabPtr.i);
       lgman.free_log_space(sz);
+      jamEntry();
       goto done;
       break;
     default:
@@ -1668,7 +1676,6 @@ Dbtup::drop_fragment_unmap_pages(Signal 
     if (!alloc_info.m_unmap_pages.isEmpty())
     {
       jam();
-      ndbout_c("waiting for unmape pages");
       signal->theData[0] = ZUNMAP_PAGES;
       signal->theData[1] = tabPtr.i;
       signal->theData[2] = fragPtr.i;
@@ -1714,6 +1721,7 @@ Dbtup::drop_fragment_unmap_pages(Signal 
     int flags= Page_cache_client::COMMIT_REQ;
     Page_cache_client pgman(this, c_pgman);
     int res= pgman.get_page(signal, req, flags);
+    jamEntry();
     m_pgman_ptr = pgman.m_ptr;
     switch(res)
     {
@@ -1744,6 +1752,7 @@ Dbtup::drop_fragment_unmap_page_callback
   Uint32 tableId = ((Page*)page.p)->m_table_id;
   Page_cache_client pgman(this, c_pgman);
   pgman.drop_page(key, page_id);
+  jamEntry();
 
   TablerecPtr tabPtr;
   tabPtr.i= tableId;
@@ -1779,10 +1788,12 @@ Dbtup::drop_fragment_free_extent(Signal 
 #if NOT_YET_UNDO_FREE_EXTENT
 	Uint32 sz= sizeof(Disk_undo::FreeExtent) >> 2;
 	(void) c_lgman->alloc_log_space(fragPtr.p->m_logfile_group_id, sz);
+        jamEntry();
 	
 	Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
 	
 	int res= lgman.get_log_buffer(signal, sz, &cb);
+        jamEntry();
 	switch(res){
 	case 0:
 	  jam();
@@ -1835,12 +1846,14 @@ Dbtup::drop_table_log_buffer_callback(Si
   
   Logfile_client::Change c[1] = {{ &drop, sizeof(drop) >> 2 } };
   Uint64 lsn = lgman.add_entry(c, 1);
+  jamEntry();
 
   Logfile_client::Request req;
   req.m_callback.m_callbackData= tablePtrI;
   req.m_callback.m_callbackIndex = DROP_TABLE_LOGSYNC_CALLBACK;
   
   int ret = lgman.sync_lsn(signal, lsn, &req, 0);
+  jamEntry();
   switch(ret){
   case 0:
     return;
@@ -1911,6 +1924,7 @@ Dbtup::drop_fragment_free_extent_log_buf
       
       Logfile_client::Change c[1] = {{ &free, sizeof(free) >> 2 } };
       Uint64 lsn = lgman.add_entry(c, 1);
+      jamEntry();
 #else
       Uint64 lsn = 0;
 #endif
@@ -1921,6 +1935,7 @@ Dbtup::drop_fragment_free_extent_log_buf
 			      fragPtr.p->m_tablespace_id);
       
       tsman.free_extent(&ext_ptr.p->m_key, lsn);
+      jamEntry();
       c_extent_hash.remove(ext_ptr);
       list.release(ext_ptr);
       

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2009-08-17 07:36:12 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2009-09-04 11:33:38 +0000
@@ -2423,6 +2423,22 @@ Dbtup::read_pseudo(const Uint32 * inBuff
     outBuffer[1] = operPtr.p->m_copy_tuple_location.m_page_no;
     outBuffer[2] = operPtr.p->m_copy_tuple_location.m_page_idx;
     break;
+  case AttributeHeader::FRAGMENT_EXTENT_SPACE:
+  {
+    Uint64 res[2];
+    disk_page_get_allocated(tabptr.p, fragptr.p, res);
+    memcpy(outBuffer + 1, res + 0, 8);
+    sz = 2;
+    break;
+  }
+  case AttributeHeader::FRAGMENT_FREE_EXTENT_SPACE:
+  {
+    Uint64 res[2];
+    disk_page_get_allocated(tabptr.p, fragptr.p, res);
+    memcpy(outBuffer + 1, res + 1, 8);
+    sz = 2;
+    break;
+  }
   default:
     return -ZATTRIBUTE_ID_ERROR;
   }

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2009-08-05 10:48:56 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2009-09-04 11:33:38 +0000
@@ -339,6 +339,83 @@ NdbColumnImpl::equal(const NdbColumnImpl
   DBUG_RETURN(true);
 }
 
+void
+NdbColumnImpl::create_pseudo_columns()
+{
+  NdbDictionary::Column::FRAGMENT=
+    NdbColumnImpl::create_pseudo("NDB$FRAGMENT");
+  NdbDictionary::Column::FRAGMENT_FIXED_MEMORY=
+    NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY");
+  NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY=
+    NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY");
+  NdbDictionary::Column::ROW_COUNT=
+    NdbColumnImpl::create_pseudo("NDB$ROW_COUNT");
+  NdbDictionary::Column::COMMIT_COUNT=
+    NdbColumnImpl::create_pseudo("NDB$COMMIT_COUNT");
+  NdbDictionary::Column::ROW_SIZE=
+    NdbColumnImpl::create_pseudo("NDB$ROW_SIZE");
+  NdbDictionary::Column::RANGE_NO=
+    NdbColumnImpl::create_pseudo("NDB$RANGE_NO");
+  NdbDictionary::Column::DISK_REF=
+    NdbColumnImpl::create_pseudo("NDB$DISK_REF");
+  NdbDictionary::Column::RECORDS_IN_RANGE=
+    NdbColumnImpl::create_pseudo("NDB$RECORDS_IN_RANGE");
+  NdbDictionary::Column::ROWID=
+    NdbColumnImpl::create_pseudo("NDB$ROWID");
+  NdbDictionary::Column::ROW_GCI=
+    NdbColumnImpl::create_pseudo("NDB$ROW_GCI");
+  NdbDictionary::Column::ANY_VALUE=
+    NdbColumnImpl::create_pseudo("NDB$ANY_VALUE");
+  NdbDictionary::Column::COPY_ROWID=
+    NdbColumnImpl::create_pseudo("NDB$COPY_ROWID");
+  NdbDictionary::Column::OPTIMIZE=
+    NdbColumnImpl::create_pseudo("NDB$OPTIMIZE");
+  NdbDictionary::Column::FRAGMENT_EXTENT_SPACE =
+    NdbColumnImpl::create_pseudo("NDB$FRAGMENT_EXTENT_SPACE");
+  NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE =
+    NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FREE_EXTENT_SPACE");
+}
+
+void
+NdbColumnImpl::destory_pseudo_columns()
+{
+  delete NdbDictionary::Column::FRAGMENT;
+  delete NdbDictionary::Column::FRAGMENT_FIXED_MEMORY;
+  delete NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY;
+  delete NdbDictionary::Column::ROW_COUNT;
+  delete NdbDictionary::Column::COMMIT_COUNT;
+  delete NdbDictionary::Column::ROW_SIZE;
+  delete NdbDictionary::Column::RANGE_NO;
+  delete NdbDictionary::Column::DISK_REF;
+  delete NdbDictionary::Column::RECORDS_IN_RANGE;
+  delete NdbDictionary::Column::ROWID;
+  delete NdbDictionary::Column::ROW_GCI;
+  delete NdbDictionary::Column::ANY_VALUE;
+  delete NdbDictionary::Column::OPTIMIZE;
+  NdbDictionary::Column::FRAGMENT= 0;
+  NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 0;
+  NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 0;
+  NdbDictionary::Column::ROW_COUNT= 0;
+  NdbDictionary::Column::COMMIT_COUNT= 0;
+  NdbDictionary::Column::ROW_SIZE= 0;
+  NdbDictionary::Column::RANGE_NO= 0;
+  NdbDictionary::Column::DISK_REF= 0;
+  NdbDictionary::Column::RECORDS_IN_RANGE= 0;
+  NdbDictionary::Column::ROWID= 0;
+  NdbDictionary::Column::ROW_GCI= 0;
+  NdbDictionary::Column::ANY_VALUE= 0;
+  NdbDictionary::Column::OPTIMIZE= 0;
+
+  delete NdbDictionary::Column::COPY_ROWID;
+  NdbDictionary::Column::COPY_ROWID = 0;
+
+  delete NdbDictionary::Column::FRAGMENT_EXTENT_SPACE;
+  NdbDictionary::Column::FRAGMENT_EXTENT_SPACE = 0;
+
+  delete NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE;
+  NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE = 0;
+}
+
 NdbDictionary::Column *
 NdbColumnImpl::create_pseudo(const char * name){
   NdbDictionary::Column * col = new NdbDictionary::Column();
@@ -414,6 +491,16 @@ NdbColumnImpl::create_pseudo(const char 
     col->m_impl.m_attrId = AttributeHeader::OPTIMIZE;
     col->m_impl.m_attrSize = 4;
     col->m_impl.m_arraySize = 1;
+  } else if(!strcmp(name, "NDB$FRAGMENT_EXTENT_SPACE")){
+    col->setType(NdbDictionary::Column::Bigunsigned);
+    col->m_impl.m_attrId = AttributeHeader::FRAGMENT_EXTENT_SPACE;
+    col->m_impl.m_attrSize = 4;
+    col->m_impl.m_arraySize = 2;
+  } else if(!strcmp(name, "NDB$FRAGMENT_FREE_EXTENT_SPACE")){
+    col->setType(NdbDictionary::Column::Bigunsigned);
+    col->m_impl.m_attrId = AttributeHeader::FRAGMENT_FREE_EXTENT_SPACE;
+    col->m_impl.m_attrSize = 4;
+    col->m_impl.m_arraySize = 2;
   } else {
     abort();
   }
@@ -7896,5 +7983,7 @@ const NdbDictionary::Column * NdbDiction
 const NdbDictionary::Column * NdbDictionary::Column::ANY_VALUE = 0;
 const NdbDictionary::Column * NdbDictionary::Column::COPY_ROWID = 0;
 const NdbDictionary::Column * NdbDictionary::Column::OPTIMIZE = 0;
+const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_EXTENT_SPACE = 0;
+const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE = 0;
 
 template class Vector<NdbDictInterface::Tx::Op>;

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2009-08-05 10:48:56 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2009-09-04 11:33:38 +0000
@@ -143,6 +143,8 @@ public:
   static const NdbColumnImpl & getImpl(const NdbDictionary::Column & t);
   NdbDictionary::Column * m_facade;
 
+  static void create_pseudo_columns();
+  static void destory_pseudo_columns();
   static NdbDictionary::Column * create_pseudo(const char *);
 
   // Get total length in bytes, used by NdbOperation

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection.cpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2009-07-03 06:34:01 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2009-09-04 11:33:38 +0000
@@ -299,36 +299,9 @@ Ndb_cluster_connection_impl(const char *
   DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%lx", (long) this));
 
   NdbMutex_Lock(g_ndb_connection_mutex);
-  if(g_ndb_connection_count++ == 0){
-    NdbDictionary::Column::FRAGMENT= 
-      NdbColumnImpl::create_pseudo("NDB$FRAGMENT");
-    NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 
-      NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY");
-    NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 
-      NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY");
-    NdbDictionary::Column::ROW_COUNT= 
-      NdbColumnImpl::create_pseudo("NDB$ROW_COUNT");
-    NdbDictionary::Column::COMMIT_COUNT= 
-      NdbColumnImpl::create_pseudo("NDB$COMMIT_COUNT");
-    NdbDictionary::Column::ROW_SIZE=
-      NdbColumnImpl::create_pseudo("NDB$ROW_SIZE");
-    NdbDictionary::Column::RANGE_NO= 
-      NdbColumnImpl::create_pseudo("NDB$RANGE_NO");
-    NdbDictionary::Column::DISK_REF= 
-      NdbColumnImpl::create_pseudo("NDB$DISK_REF");
-    NdbDictionary::Column::RECORDS_IN_RANGE= 
-      NdbColumnImpl::create_pseudo("NDB$RECORDS_IN_RANGE");
-    NdbDictionary::Column::ROWID= 
-      NdbColumnImpl::create_pseudo("NDB$ROWID");
-    NdbDictionary::Column::ROW_GCI= 
-      NdbColumnImpl::create_pseudo("NDB$ROW_GCI");
-    NdbDictionary::Column::ANY_VALUE= 
-      NdbColumnImpl::create_pseudo("NDB$ANY_VALUE");
-    NdbDictionary::Column::COPY_ROWID= 
-      NdbColumnImpl::create_pseudo("NDB$COPY_ROWID");
-    NdbDictionary::Column::OPTIMIZE=
-      NdbColumnImpl::create_pseudo("NDB$OPTIMIZE");
-
+  if(g_ndb_connection_count++ == 0)
+  {
+    NdbColumnImpl::create_pseudo_columns();
     g_eventLogger->createConsoleHandler();
     g_eventLogger->setCategory("NdbApi");
     g_eventLogger->enable(Logger::LL_ON, Logger::LL_ERROR);
@@ -424,37 +397,9 @@ Ndb_cluster_connection_impl::~Ndb_cluste
     free(m_name);
 
   NdbMutex_Lock(g_ndb_connection_mutex);
-  if(--g_ndb_connection_count == 0){
-    delete NdbDictionary::Column::FRAGMENT; 
-    delete NdbDictionary::Column::FRAGMENT_FIXED_MEMORY;
-    delete NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY;
-    delete NdbDictionary::Column::ROW_COUNT;
-    delete NdbDictionary::Column::COMMIT_COUNT;
-    delete NdbDictionary::Column::ROW_SIZE;
-    delete NdbDictionary::Column::RANGE_NO;
-    delete NdbDictionary::Column::DISK_REF;
-    delete NdbDictionary::Column::RECORDS_IN_RANGE;
-    delete NdbDictionary::Column::ROWID;
-    delete NdbDictionary::Column::ROW_GCI;
-    delete NdbDictionary::Column::ANY_VALUE;
-    delete NdbDictionary::Column::OPTIMIZE;
-    NdbDictionary::Column::FRAGMENT= 0;
-    NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 0;
-    NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 0;
-    NdbDictionary::Column::ROW_COUNT= 0;
-    NdbDictionary::Column::COMMIT_COUNT= 0;
-    NdbDictionary::Column::ROW_SIZE= 0;
-    NdbDictionary::Column::RANGE_NO= 0;
-    NdbDictionary::Column::DISK_REF= 0;
-    NdbDictionary::Column::RECORDS_IN_RANGE= 0;
-    NdbDictionary::Column::ROWID= 0;
-    NdbDictionary::Column::ROW_GCI= 0;
-    NdbDictionary::Column::ANY_VALUE= 0;
-    NdbDictionary::Column::OPTIMIZE= 0;
-
-    delete NdbDictionary::Column::COPY_ROWID;
-    NdbDictionary::Column::COPY_ROWID = 0;
-    
+  if(--g_ndb_connection_count == 0)
+  {
+    NdbColumnImpl::destory_pseudo_columns();
   }
   NdbMutex_Unlock(g_ndb_connection_mutex);
 

=== modified file 'storage/ndb/tools/desc.cpp'
--- a/storage/ndb/tools/desc.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/tools/desc.cpp	2009-09-04 11:33:38 +0000
@@ -303,6 +303,9 @@ void print_part_info(Ndb* pNdb, NDBT_Tab
     { "Commit count", 0, NdbDictionary::Column::COMMIT_COUNT },
     { "Frag fixed memory", 0, NdbDictionary::Column::FRAGMENT_FIXED_MEMORY },
     { "Frag varsized memory", 0, NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY },
+    { "Extent_space", 0, NdbDictionary::Column::FRAGMENT_EXTENT_SPACE },
+    { "Free extent_space", 0, NdbDictionary::Column::FRAGMENT_FREE_EXTENT_SPACE },
+
     { 0, 0, 0 }
   };
 


Attachment: [text/bzr-bundle] bzr/jonas@mysql.com-20090904113338-65p55dyr4v62k5rg.bundle
Thread
bzr commit into mysql-5.1-telco-7.0 branch (jonas:2984)Jonas Oreland4 Sep