mirror of
				https://github.com/isar/libmdbx.git
				synced 2025-10-31 15:38:57 +08:00 
			
		
		
		
	lmdb: update mdb_chk for checkpoints, minor cosmetics.
This is 9/9 for https://github.com/ReOpen/ReOpenLDAP/issues/1 and https://github.com/ReOpen/ReOpenLDAP/issues/2 Change-Id: I05f59313b4346c08bcd63d62e6c48a5f53c47852
This commit is contained in:
		
							
								
								
									
										4
									
								
								lmdb.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								lmdb.h
									
									
									
									
									
								
							| @@ -446,6 +446,8 @@ typedef struct MDB_envinfo { | |||||||
| 	size_t	me_tail_txnid;			/**< ID of the last reader transaction */ | 	size_t	me_tail_txnid;			/**< ID of the last reader transaction */ | ||||||
| 	unsigned me_maxreaders;		/**< max reader slots in the environment */ | 	unsigned me_maxreaders;		/**< max reader slots in the environment */ | ||||||
| 	unsigned me_numreaders;		/**< max reader slots used in the environment */ | 	unsigned me_numreaders;		/**< max reader slots used in the environment */ | ||||||
|  | 	size_t me_meta1_txnid, me_meta1_sign; | ||||||
|  | 	size_t me_meta2_txnid, me_meta2_sign; | ||||||
| } MDB_envinfo; | } MDB_envinfo; | ||||||
|  |  | ||||||
| 	/** @brief Return the LMDB library version information. | 	/** @brief Return the LMDB library version information. | ||||||
| @@ -695,7 +697,7 @@ int  mdb_env_stat(MDB_env *env, MDB_stat *stat); | |||||||
| 	 * @param[out] stat The address of an #MDB_envinfo structure | 	 * @param[out] stat The address of an #MDB_envinfo structure | ||||||
| 	 * 	where the information will be copied | 	 * 	where the information will be copied | ||||||
| 	 */ | 	 */ | ||||||
| int  mdb_env_info(MDB_env *env, MDB_envinfo *stat); | int  mdb_env_info(MDB_env *env, MDB_envinfo *info); | ||||||
|  |  | ||||||
| 	/** @brief Flush the data buffers to disk. | 	/** @brief Flush the data buffers to disk. | ||||||
| 	 * | 	 * | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								mdb.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								mdb.c
									
									
									
									
									
								
							| @@ -9039,21 +9039,32 @@ mdb_env_stat(MDB_env *env, MDB_stat *arg) | |||||||
| int ESECT | int ESECT | ||||||
| mdb_env_info(MDB_env *env, MDB_envinfo *arg) | mdb_env_info(MDB_env *env, MDB_envinfo *arg) | ||||||
| { | { | ||||||
| 	MDB_meta *meta; | 	MDB_meta *meta, *m1, *m2; | ||||||
|  |  | ||||||
| 	if (env == NULL || arg == NULL) | 	if (env == NULL || arg == NULL) | ||||||
| 		return EINVAL; | 		return EINVAL; | ||||||
|  |  | ||||||
| 	meta = mdb_meta_head_r(env); | 	m1 = METAPAGE_1(env); | ||||||
| 	arg->me_mapaddr = meta->mm_address; | 	m2 = METAPAGE_2(env); | ||||||
|  |  | ||||||
| 	arg->me_mapsize = env->me_mapsize; | 	arg->me_mapsize = env->me_mapsize; | ||||||
| 	arg->me_maxreaders = env->me_maxreaders; | 	arg->me_maxreaders = env->me_maxreaders; | ||||||
| 	arg->me_numreaders = env->me_txns->mti_numreaders; | 	arg->me_numreaders = env->me_txns->mti_numreaders; | ||||||
|  |  | ||||||
| 	arg->me_last_pgno = meta->mm_last_pg; | 	do { | ||||||
| 	arg->me_last_txnid = meta->mm_txnid; | 		meta = mdb_meta_head_r(env); | ||||||
| 	arg->me_tail_txnid = 0; | 		arg->me_meta1_txnid = m1->mm_txnid; | ||||||
|  | 		arg->me_meta1_sign = m1->mm_datasync_sign; | ||||||
|  | 		arg->me_meta2_txnid = m2->mm_txnid; | ||||||
|  | 		arg->me_meta2_sign = m2->mm_datasync_sign; | ||||||
|  | 		arg->me_last_pgno = meta->mm_last_pg; | ||||||
|  | 		arg->me_last_txnid = meta->mm_txnid; | ||||||
|  | 	} while (unlikely( meta->mm_txnid != env->me_txns->mti_txnid | ||||||
|  | 			|| arg->me_meta1_sign != m1->mm_datasync_sign | ||||||
|  | 			|| arg->me_meta2_sign != m2->mm_datasync_sign )); | ||||||
|  |  | ||||||
|  | 	arg->me_mapaddr = meta->mm_address; | ||||||
|  | 	arg->me_tail_txnid = 0; | ||||||
| 	MDB_reader *r = env->me_txns->mti_readers; | 	MDB_reader *r = env->me_txns->mti_readers; | ||||||
| 	int i; | 	int i; | ||||||
| 	arg->me_tail_txnid = arg->me_last_txnid; | 	arg->me_tail_txnid = arg->me_last_txnid; | ||||||
|   | |||||||
							
								
								
									
										70
									
								
								mdb_chk.c
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								mdb_chk.c
									
									
									
									
									
								
							| @@ -244,10 +244,10 @@ static long handle_freedb(size_t record_number, MDB_val *key, MDB_val* data) { | |||||||
| 				pg += span; | 				pg += span; | ||||||
| 				for (; i >= span && iptr[i - span] == pg; span++, pg++) ; | 				for (; i >= span && iptr[i - span] == pg; span++, pg++) ; | ||||||
| 			} | 			} | ||||||
| 			if (verbose > 1) | 			if (verbose > 2) | ||||||
| 				print(" - transaction %zu, %zd pages, maxspan %zd%s\n", | 				print(" - transaction %zu, %zd pages, maxspan %zd%s\n", | ||||||
| 					*(size_t *)key->mv_data, number, span, bad); | 					*(size_t *)key->mv_data, number, span, bad); | ||||||
| 			if (verbose > 2) { | 			if (verbose > 3) { | ||||||
| 				int j = number - 1; | 				int j = number - 1; | ||||||
| 				while (j >= 0) { | 				while (j >= 0) { | ||||||
| 					pg = iptr[j]; | 					pg = iptr[j]; | ||||||
| @@ -430,6 +430,21 @@ static void usage(char *prog) | |||||||
| 	exit(EXIT_FAILURE); | 	exit(EXIT_FAILURE); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const char* meta_synctype(size_t sign) { | ||||||
|  | 	switch(sign) { | ||||||
|  | 	case 0: | ||||||
|  | 		return "legacy/unknown"; | ||||||
|  | 	case 1: | ||||||
|  | 		return "weak"; | ||||||
|  | 	default: | ||||||
|  | 		return "steady"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int meta_lt(size_t txn1, size_t sign1, size_t txn2, size_t sign2) { | ||||||
|  | 	return ((sign1 > 1) == (sign2 > 1)) ? txn1 < txn2 : sign2 > 1; | ||||||
|  | } | ||||||
|  |  | ||||||
| int main(int argc, char *argv[]) | int main(int argc, char *argv[]) | ||||||
| { | { | ||||||
| 	int i, rc; | 	int i, rc; | ||||||
| @@ -437,6 +452,7 @@ int main(int argc, char *argv[]) | |||||||
| 	char *envname; | 	char *envname; | ||||||
| 	int envflags = 0; | 	int envflags = 0; | ||||||
| 	long problems_maindb = 0, problems_freedb = 0, problems_deep = 0; | 	long problems_maindb = 0, problems_freedb = 0, problems_deep = 0; | ||||||
|  | 	int problems_meta = 0; | ||||||
| 	size_t n; | 	size_t n; | ||||||
|  |  | ||||||
| 	if (argc < 2) { | 	if (argc < 2) { | ||||||
| @@ -480,6 +496,8 @@ int main(int argc, char *argv[]) | |||||||
| 	signal(SIGTERM, signal_hanlder); | 	signal(SIGTERM, signal_hanlder); | ||||||
|  |  | ||||||
| 	envname = argv[optind]; | 	envname = argv[optind]; | ||||||
|  | 	print("Running mdb_chk for '%s'...\n", envname); | ||||||
|  |  | ||||||
| 	rc = mdb_env_create(&env); | 	rc = mdb_env_create(&env); | ||||||
| 	if (rc) { | 	if (rc) { | ||||||
| 		error("mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc)); | 		error("mdb_env_create failed, error %d %s\n", rc, mdb_strerror(rc)); | ||||||
| @@ -523,15 +541,50 @@ int main(int argc, char *argv[]) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (verbose) { | 	if (verbose) { | ||||||
| 		print(" - map size %zu (%.1fMb, %.1fGb)\n", info.me_mapsize, | 		double k = 1024.0; | ||||||
| 			  (double) info.me_mapsize / (1024 * 1024), | 		const char sf[] = "KMGTPEZY"; /* LY: Kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta! */ | ||||||
| 			  (double) info.me_mapsize / (1024 * 1024 * 1024)); | 		for(i = 0; sf[i+1] && info.me_mapsize / k > 1000.0; ++i) | ||||||
|  | 			k *= 1024; | ||||||
|  | 		print(" - map size %zu (%.1f%cb)\n", info.me_mapsize, | ||||||
|  | 			  info.me_mapsize / k, sf[i]); | ||||||
| 		if (info.me_mapaddr) | 		if (info.me_mapaddr) | ||||||
| 			print(" - mapaddr %p\n", info.me_mapaddr); | 			print(" - mapaddr %p\n", info.me_mapaddr); | ||||||
| 		print(" - pagesize %u, max keysize %zu, max readers %u\n", | 		print(" - pagesize %u, max keysize %zu, max readers %u\n", | ||||||
| 			  stat.ms_psize, maxkeysize, info.me_maxreaders); | 			  stat.ms_psize, maxkeysize, info.me_maxreaders); | ||||||
| 		print(" - last txn %zu, tail %zu (%zi)\n", info.me_last_txnid, | 		print(" - transactions: last %zu, bottom %zu, lag reading %zi\n", info.me_last_txnid, | ||||||
| 			  info.me_tail_txnid, info.me_tail_txnid - info.me_last_txnid); | 			  info.me_tail_txnid, info.me_last_txnid - info.me_tail_txnid); | ||||||
|  |  | ||||||
|  | 		print(" - meta-1: %s %zu, %s", | ||||||
|  | 			   meta_synctype(info.me_meta1_sign), info.me_meta1_txnid, | ||||||
|  | 			   meta_lt(info.me_meta1_txnid, info.me_meta1_sign, | ||||||
|  | 					   info.me_meta2_txnid, info.me_meta2_sign) ? "tail" : "head"); | ||||||
|  | 		print(info.me_meta1_txnid > info.me_last_txnid | ||||||
|  | 			  ? ", rolled-back %zu (%zu >>> %zu)\n" : "\n", | ||||||
|  | 			  info.me_meta1_txnid - info.me_last_txnid, | ||||||
|  | 			  info.me_meta1_txnid, info.me_last_txnid); | ||||||
|  |  | ||||||
|  | 		print(" - meta-2: %s %zu, %s", | ||||||
|  | 			   meta_synctype(info.me_meta2_sign), info.me_meta2_txnid, | ||||||
|  | 			   meta_lt(info.me_meta2_txnid, info.me_meta2_sign, | ||||||
|  | 					   info.me_meta1_txnid, info.me_meta1_sign) ? "tail" : "head"); | ||||||
|  | 		print(info.me_meta2_txnid > info.me_last_txnid | ||||||
|  | 			  ? ", rolled-back %zu (%zu >>> %zu)\n" : "\n", | ||||||
|  | 			  info.me_meta2_txnid - info.me_last_txnid, | ||||||
|  | 			  info.me_meta2_txnid, info.me_last_txnid); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (! meta_lt(info.me_meta1_txnid, info.me_meta1_sign, | ||||||
|  | 			info.me_meta2_txnid, info.me_meta2_sign) | ||||||
|  | 		&& info.me_meta1_txnid != info.me_last_txnid) { | ||||||
|  | 		print(" - meta1 txn-id mismatch\n"); | ||||||
|  | 		++problems_meta; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (! meta_lt(info.me_meta2_txnid, info.me_meta2_sign, | ||||||
|  | 			info.me_meta1_txnid, info.me_meta1_sign) | ||||||
|  | 		&& info.me_meta2_txnid != info.me_last_txnid) { | ||||||
|  | 		print(" - meta2 txn-id mismatch\n"); | ||||||
|  | 		++problems_meta; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); | 	rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); | ||||||
| @@ -610,9 +663,10 @@ bailout: | |||||||
| 	free(pagemap); | 	free(pagemap); | ||||||
| 	if (rc) | 	if (rc) | ||||||
| 		return EXIT_FAILURE + 2; | 		return EXIT_FAILURE + 2; | ||||||
| 	if (problems_maindb || problems_freedb) | 	if (problems_meta || problems_maindb || problems_freedb) | ||||||
| 		return EXIT_FAILURE + 1; | 		return EXIT_FAILURE + 1; | ||||||
| 	if (problems_deep) | 	if (problems_deep) | ||||||
| 		return EXIT_FAILURE; | 		return EXIT_FAILURE; | ||||||
|  | 	print("No error is detected.\n"); | ||||||
| 	return EXIT_SUCCESS; | 	return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user