diff --git a/mysql-test/r/ndb_restore.result b/mysql-test/r/ndb_restore.result
index 7dc4057e615f0706627600bc5bf5f390bf30c2d9..c745869daee25e745749884cb4b0afd37a62fde1 100644
--- a/mysql-test/r/ndb_restore.result
+++ b/mysql-test/r/ndb_restore.result
@@ -467,3 +467,116 @@ Create table test/def/t2_c failed: Translate frm error
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 drop table if exists t2_c;
 520093696,<the_backup_id>
+DROP DATABASE IF EXISTS BANK;
+CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin;
+USE BANK;
+SHOW TABLES;
+Tables_in_BANK
+ACCOUNT
+GL
+ACCOUNT_TYPE
+TRANSACTION
+SYSTEM_VALUES
+SELECT * FROM GL            ORDER BY TIME,ACCOUNT_TYPE;
+TIME	ACCOUNT_TYPE	BALANCE	DEPOSIT_COUNT	DEPOSIT_SUM	WITHDRAWAL_COUNT	WITHDRAWAL_SUM	PURGED
+0	0	10000000	0	0	0	0	1
+0	1	30000	0	0	0	0	1
+0	2	20000	0	0	0	0	1
+0	3	20000	0	0	0	0	1
+0	4	20000	0	0	0	0	1
+1	0	10000000	0	0	0	0	1
+1	1	30000	0	0	0	0	1
+1	2	20000	0	0	0	0	1
+1	3	20000	0	0	0	0	1
+1	4	20000	0	0	0	0	1
+2	0	9857062	54	225197	76	368135	1
+2	1	60601	174	822920	181	792319	1
+2	2	68832	117	531214	98	482382	1
+2	3	83550	106	521953	104	458403	1
+2	4	19955	118	532084	110	532129	1
+3	0	9732896	62	289563	88	413729	1
+3	1	51056	202	895888	193	905433	0
+3	2	67183	122	596787	127	598436	1
+3	3	97669	159	761743	141	747624	1
+3	4	141196	140	727808	136	606567	1
+4	0	9616621	138	603930	142	720205	0
+4	1	178927	348	1741521	344	1613650	0
+4	2	52141	236	1169929	232	1184971	0
+4	3	48938	228	1147957	244	1196688	0
+4	4	193373	246	1257982	234	1205805	0
+5	0	9515281	156	726253	166	827593	0
+5	1	253798	597	2840640	545	2765769	0
+5	2	102776	362	1821680	364	1771045	0
+5	3	87349	359	1778652	375	1740241	0
+5	4	130796	351	1727448	375	1790025	0
+SELECT * FROM ACCOUNT       ORDER BY ACCOUNT_ID;
+ACCOUNT_ID	OWNER	BALANCE	ACCOUNT_TYPE
+0	0	9531306	0
+1	3001	123844	1
+2	3002	30800	2
+3	3003	3133	3
+4	3004	6524	4
+5	3005	80152	1
+6	3006	107390	1
+7	3007	69448	2
+8	3008	663	3
+9	3009	136740	4
+SELECT COUNT(*) FROM TRANSACTION;
+COUNT(*)
+6649
+SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID;
+SYSTEM_VALUES_ID	VALUE
+0	4767
+1	6
+TRUNCATE GL;
+TRUNCATE ACCOUNT;
+TRUNCATE TRANSACTION;
+TRUNCATE SYSTEM_VALUES;
+TRUNCATE ACCOUNT_TYPE;
+SELECT * FROM GL            ORDER BY TIME,ACCOUNT_TYPE;
+TIME	ACCOUNT_TYPE	BALANCE	DEPOSIT_COUNT	DEPOSIT_SUM	WITHDRAWAL_COUNT	WITHDRAWAL_SUM	PURGED
+0	0	10000000	0	0	0	0	1
+0	1	30000	0	0	0	0	1
+0	2	20000	0	0	0	0	1
+0	3	20000	0	0	0	0	1
+0	4	20000	0	0	0	0	1
+1	0	10000000	0	0	0	0	1
+1	1	30000	0	0	0	0	1
+1	2	20000	0	0	0	0	1
+1	3	20000	0	0	0	0	1
+1	4	20000	0	0	0	0	1
+2	0	10000000	0	0	0	0	1
+2	1	30000	0	0	0	0	1
+2	2	20000	0	0	0	0	1
+2	3	20000	0	0	0	0	1
+2	4	20000	0	0	0	0	1
+3	0	9963591	14	59111	19	95520	0
+3	1	44264	49	255559	53	241295	0
+3	2	25515	39	177806	36	172291	0
+3	3	16779	26	129200	29	132421	0
+3	4	39851	43	182771	34	162920	0
+4	0	9733661	141	632616	162	862546	0
+4	1	63853	426	2005337	415	1985748	0
+4	2	140473	314	1548632	297	1433674	0
+4	3	13481	310	1528043	324	1531341	0
+4	4	138532	316	1540206	309	1441525	0
+SELECT * FROM ACCOUNT       ORDER BY ACCOUNT_ID;
+ACCOUNT_ID	OWNER	BALANCE	ACCOUNT_TYPE
+0	0	9679579	0
+1	3001	18130	1
+2	3002	12318	2
+3	3003	3049	3
+4	3004	39517	4
+5	3005	37051	1
+6	3006	144497	1
+7	3007	130670	2
+8	3008	13747	3
+9	3009	11442	4
+SELECT COUNT(*) FROM TRANSACTION;
+COUNT(*)
+4056
+SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID;
+SYSTEM_VALUES_ID	VALUE
+0	2297
+1	5
+DROP DATABASE BANK;
diff --git a/mysql-test/std_data/ndb_backup50/BACKUP-1-0.1.Data b/mysql-test/std_data/ndb_backup50/BACKUP-1-0.1.Data
new file mode 100644
index 0000000000000000000000000000000000000000..32494d5a1e718a0a4d67d65aafe42f5a3cd316b9
Binary files /dev/null and b/mysql-test/std_data/ndb_backup50/BACKUP-1-0.1.Data differ
diff --git a/mysql-test/std_data/ndb_backup50/BACKUP-1-0.2.Data b/mysql-test/std_data/ndb_backup50/BACKUP-1-0.2.Data
new file mode 100644
index 0000000000000000000000000000000000000000..2141fb0a6e4c93e424dbb0f090a22cfd621ffa4a
Binary files /dev/null and b/mysql-test/std_data/ndb_backup50/BACKUP-1-0.2.Data differ
diff --git a/mysql-test/std_data/ndb_backup50/BACKUP-1.1.log b/mysql-test/std_data/ndb_backup50/BACKUP-1.1.log
new file mode 100644
index 0000000000000000000000000000000000000000..e4e114d4b46482f55d1d5bfb82c13232416641bf
Binary files /dev/null and b/mysql-test/std_data/ndb_backup50/BACKUP-1.1.log differ
diff --git a/mysql-test/std_data/ndb_backup50/BACKUP-1.2.log b/mysql-test/std_data/ndb_backup50/BACKUP-1.2.log
new file mode 100644
index 0000000000000000000000000000000000000000..a1c89b7015c91195748ff00763d88ec60d331924
Binary files /dev/null and b/mysql-test/std_data/ndb_backup50/BACKUP-1.2.log differ
diff --git a/mysql-test/std_data/ndb_backup51/BACKUP-1-0.1.Data b/mysql-test/std_data/ndb_backup51/BACKUP-1-0.1.Data
new file mode 100644
index 0000000000000000000000000000000000000000..22b99ddc18d7017df9a2ef08cd5f3fc0927cb480
Binary files /dev/null and b/mysql-test/std_data/ndb_backup51/BACKUP-1-0.1.Data differ
diff --git a/mysql-test/std_data/ndb_backup51/BACKUP-1-0.2.Data b/mysql-test/std_data/ndb_backup51/BACKUP-1-0.2.Data
new file mode 100644
index 0000000000000000000000000000000000000000..159cff9305334e2b5162078a6c1e67f60bcec8ab
Binary files /dev/null and b/mysql-test/std_data/ndb_backup51/BACKUP-1-0.2.Data differ
diff --git a/mysql-test/t/ndb_restore.test b/mysql-test/t/ndb_restore.test
index f11324492c22e309d4f8c101848012f7f9f69f2f..01fdb2ecc5a73ff2bd1194b89bf2fa935e00bd6c 100644
--- a/mysql-test/t/ndb_restore.test
+++ b/mysql-test/t/ndb_restore.test
@@ -373,3 +373,38 @@ drop table if exists t2_c;
 --exec $NDB_TOOLS_DIR/ndb_select_all --no-defaults -d sys -D , SYSTAB_0 | grep 520093696, | sed "s/,$the_backup_id/,<the_backup_id>/"
 
 # End of 4.1 tests
+
+#
+# Bug #18594 ndb_restore log boken in 5.1
+#
+
+--disable_warnings
+DROP DATABASE IF EXISTS BANK;
+--enable_warnings
+CREATE DATABASE BANK default charset=latin1 default collate=latin1_bin;
+USE BANK;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -p 1 -m -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup51 >> $NDB_TOOLS_OUTPUT
+SHOW TABLES;
+SELECT * FROM GL            ORDER BY TIME,ACCOUNT_TYPE;
+SELECT * FROM ACCOUNT       ORDER BY ACCOUNT_ID;
+SELECT COUNT(*) FROM TRANSACTION;
+SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID;
+
+#
+# verify restore of 5.0 backup
+# here we must use the already created tables as restoring the old
+# table definitions will not work
+#
+TRUNCATE GL;
+TRUNCATE ACCOUNT;
+TRUNCATE TRANSACTION;
+TRUNCATE SYSTEM_VALUES;
+TRUNCATE ACCOUNT_TYPE;
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup50 >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -p 1 -r $MYSQL_TEST_DIR/std_data/ndb_backup50 >> $NDB_TOOLS_OUTPUT
+SELECT * FROM GL            ORDER BY TIME,ACCOUNT_TYPE;
+SELECT * FROM ACCOUNT       ORDER BY ACCOUNT_ID;
+SELECT COUNT(*) FROM TRANSACTION;
+SELECT * FROM SYSTEM_VALUES ORDER BY SYSTEM_VALUES_ID;
+DROP DATABASE BANK;
diff --git a/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp b/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp
index ac41b78fef11fd5fb0bff8b02e59049cfd05269f..9fa5800c12009cc29c506887cd56b0bdd0791f2b 100644
--- a/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp
+++ b/storage/ndb/src/kernel/blocks/backup/BackupFormat.hpp
@@ -146,6 +146,17 @@ struct BackupFormat {
       Uint32 FragId;
       Uint32 Data[1]; // Len = Length - 3
     };
+
+    /**
+     * Log Entry pre NDBD_FRAGID_VERSION
+     */
+    struct LogEntry_no_fragid {
+      Uint32 Length;
+      Uint32 TableId;
+      // If TriggerEvent & 0x10000 == true then GCI is right after data
+      Uint32 TriggerEvent;
+      Uint32 Data[1]; // Len = Length - 2
+    };
   };
 
   /**
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index a1a270c724a9b8a5b5413166af09e71611bc1693..deeab1f1a2b404850944883a83e475fd2b866727 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -43,6 +43,7 @@
 #include <my_sys.h>
 #include <NdbEnv.h>
 #include <NdbMem.h>
+#include <ndb_version.h>
 
 #define DEBUG_PRINT 0
 #define INCOMPATIBLE_VERSION -2
@@ -1963,7 +1964,8 @@ indexTypeMapping[] = {
 int
 NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
 				 const Uint32 * data, Uint32 len,
-				 bool fullyQualifiedNames)
+				 bool fullyQualifiedNames,
+                                 Uint32 version)
 {
   SimplePropertiesLinearReader it(data, len);
   DictTabInfo::Table *tableDesc;
@@ -2142,7 +2144,14 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
   * ret = impl;
 
   NdbMem_Free((void*)tableDesc);
-  DBUG_ASSERT(impl->m_fragmentCount > 0);
+  if (version < MAKE_VERSION(5,1,3))
+  {
+    ;
+  } 
+  else
+  {
+    DBUG_ASSERT(impl->m_fragmentCount > 0);
+  }
   DBUG_RETURN(0);
 }
 
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index 01aa6b09c90cd544d0214fef1622912dc56e5fb0..38033e7237bdf0c48ed0eb59f71d587cb6367f05 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -454,7 +454,8 @@ public:
 
   static int parseTableInfo(NdbTableImpl ** dst, 
 			    const Uint32 * data, Uint32 len,
-			    bool fullyQualifiedNames);
+			    bool fullyQualifiedNames,
+                            Uint32 version= 0xFFFFFFFF);
 
   static int parseFileInfo(NdbFileImpl &dst,
 			   const Uint32 * data, Uint32 len);
diff --git a/storage/ndb/tools/restore/Restore.cpp b/storage/ndb/tools/restore/Restore.cpp
index 779cddd1a38cc9aaf9a4ef863a784e0c760ba151..6bb790b2d697a32f2961b3e16f61d65560536e4c 100644
--- a/storage/ndb/tools/restore/Restore.cpp
+++ b/storage/ndb/tools/restore/Restore.cpp
@@ -25,6 +25,7 @@
 #include <SimpleProperties.hpp>
 #include <signaldata/DictTabInfo.hpp>
 #include <ndb_limits.h>
+#include <NdbAutoPtr.hpp>
 
 #include "../../../../sql/ha_ndbcluster_tables.h"
 
@@ -291,6 +292,7 @@ RestoreMetaData::markSysTables()
         strcmp(tableName, "NDB$EVENTS_0") == 0 ||
         strcmp(tableName, "sys/def/SYSTAB_0") == 0 ||
         strcmp(tableName, "sys/def/NDB$EVENTS_0") == 0 ||
+        strcmp(tableName, "cluster_replication/def/" NDB_APPLY_TABLE) == 0 ||
         strcmp(tableName, NDB_REP_DB "/def/" NDB_APPLY_TABLE) == 0 ||
         strcmp(tableName, NDB_REP_DB "/def/" NDB_SCHEMA_TABLE)== 0 )
       table->isSysTable = true;
@@ -377,7 +379,8 @@ bool
 RestoreMetaData::parseTableDescriptor(const Uint32 * data, Uint32 len)
 {
   NdbTableImpl* tableImpl = 0;
-  int ret = NdbDictInterface::parseTableInfo(&tableImpl, data, len, false);
+  int ret = NdbDictInterface::parseTableInfo(&tableImpl, data, len, false,
+                                             m_fileHeader.NdbVersion);
   
   if (ret != 0) {
     err << "parseTableInfo " << " failed" << endl;
@@ -956,13 +959,16 @@ RestoreLogIterator::RestoreLogIterator(const RestoreMetaData & md)
 }
 
 const LogEntry *
-RestoreLogIterator::getNextLogEntry(int & res, bool *alloc_flag) {
+RestoreLogIterator::getNextLogEntry(int & res) {
   // Read record length
   typedef BackupFormat::LogFile::LogEntry LogE;
-
+  typedef BackupFormat::LogFile::LogEntry_no_fragid LogE_no_fragid;
+  const Uint32 offset= 3;
+  assert(offset == (offsetof(LogE, Data) >> 2) - 1);
   LogE * logE= 0;
   Uint32 len= ~0;
   const Uint32 stopGCP = m_metaData.getStopGCP();
+  NdbAutoPtr<char> ap1;
   do {
     if (buffer_read_ahead(&len, sizeof(Uint32), 1) != 1){
       res= -1;
@@ -988,21 +994,33 @@ RestoreLogIterator::getNextLogEntry(int & res, bool *alloc_flag) {
         We set FragId to 0 in older versions (these versions
         do not support restore of user defined partitioned
         tables.
+
+        These log entries miss one Uint32 FragId, hence missing_len=1
+
+        Reconstruct a new log entry with old.
       */
+      const Uint32 missing_len= 1;
+      assert((offsetof(LogE, Data) - offsetof(LogE_no_fragid, Data)) >> 2 ==
+             missing_len);
+      LogE_no_fragid * logE_no_fragid= (LogE_no_fragid *)logE;
+      
       int i;
-      LogE *tmpLogE = (LogE*)NdbMem_Allocate(data_len + 4);
+      LogE *tmpLogE= (LogE*)NdbMem_Allocate(data_len + missing_len*4);
       if (!tmpLogE)
       {
         res = -2;
         return 0;
       }
-      tmpLogE->Length = logE->Length;
-      tmpLogE->TableId = logE->TableId;
-      tmpLogE->TriggerEvent = logE->TriggerEvent;
-      tmpLogE->FragId = 0;
-      for (i = 0; i < len - 3; i++)
-        tmpLogE->Data[i] = logE->Data[i-1];
-      *alloc_flag= true;
+      ap1.reset((char*)tmpLogE);
+      bzero(tmpLogE, data_len + missing_len*4);
+      /* correct len to reflect new logEntry version length */
+      len+= missing_len;
+      tmpLogE->Length = logE_no_fragid->Length;
+      tmpLogE->TableId = logE_no_fragid->TableId;
+      tmpLogE->TriggerEvent = logE_no_fragid->TriggerEvent;
+      for (i = 0; i < len - offset; i++)
+        tmpLogE->Data[i] = logE_no_fragid->Data[i];
+      logE= tmpLogE;
     }
     logE->TableId= ntohl(logE->TableId);
     logE->TriggerEvent= ntohl(logE->TriggerEvent);
@@ -1012,7 +1030,7 @@ RestoreLogIterator::getNextLogEntry(int & res, bool *alloc_flag) {
     
     if(hasGcp){
       len--;
-      m_last_gci = ntohl(logE->Data[len-2]);
+      m_last_gci = ntohl(logE->Data[len-offset]);
     }
   } while(m_last_gci > stopGCP + 1);
   
@@ -1036,7 +1054,7 @@ RestoreLogIterator::getNextLogEntry(int & res, bool *alloc_flag) {
   m_logEntry.clear();
 
   AttributeHeader * ah = (AttributeHeader *)&logE->Data[0];
-  AttributeHeader *end = (AttributeHeader *)&logE->Data[len - 3];
+  AttributeHeader *end = (AttributeHeader *)&logE->Data[len - offset];
   AttributeS *  attr;
   m_logEntry.m_frag_id = ntohl(logE->FragId);
   while(ah < end){
diff --git a/storage/ndb/tools/restore/Restore.hpp b/storage/ndb/tools/restore/Restore.hpp
index 516225cfab6aefff23d59d0fec42fc97e650b959..8698d0943e2628dab464840ce56a1e98d572edd7 100644
--- a/storage/ndb/tools/restore/Restore.hpp
+++ b/storage/ndb/tools/restore/Restore.hpp
@@ -386,7 +386,7 @@ public:
   RestoreLogIterator(const RestoreMetaData &);
   virtual ~RestoreLogIterator() {};
 
-  const LogEntry * getNextLogEntry(int & res, bool *alloc_flag);
+  const LogEntry * getNextLogEntry(int & res);
 };
 
 NdbOut& operator<<(NdbOut& ndbout, const TableS&);
diff --git a/storage/ndb/tools/restore/restore_main.cpp b/storage/ndb/tools/restore/restore_main.cpp
index bf57664ba9bf89bb8d47e8351e78475d23bdaa6e..20bcb552a1a092c4f9a1510fbeaa8f92b6ea2fbd 100644
--- a/storage/ndb/tools/restore/restore_main.cpp
+++ b/storage/ndb/tools/restore/restore_main.cpp
@@ -615,14 +615,11 @@ main(int argc, char** argv)
       }
       
       const LogEntry * logEntry = 0;
-      bool alloc_flag = false;
-      while ((logEntry = logIter.getNextLogEntry(res= 0, &alloc_flag)) != 0)
+      while ((logEntry = logIter.getNextLogEntry(res= 0)) != 0)
       {
 	if (checkSysTable(logEntry->m_table))
 	  for(Uint32 i= 0; i < g_consumers.size(); i++)
 	    g_consumers[i]->logEntry(* logEntry);
-        if (alloc_flag)
-          NdbMem_Free((void*)logEntry);
       }
       if (res < 0)
       {