void csync_db_fin(void *vmx, const char *err) { db_stmt_p stmt = (db_stmt_p) vmx; int rc, busyc = 0; if (vmx == NULL) return; csync_debug(2, "SQL Query finished.\n"); while (1) { rc = db_stmt_close(stmt); if ( rc != DB_BUSY ) break; if (busyc++ > get_dblock_timeout()) { db = 0; csync_fatal(DEADLOCK_MESSAGE); } csync_debug(2, "Database is busy, sleeping a sec.\n"); sleep(1); } if ( rc != DB_OK && err ) csync_fatal("Database Error: %s [%d]: %s\n", err, rc, db_errmsg(db)); csync_db_maycommit(); in_sql_query--; }
int csync_db_next(void *vmx, const char *err, int *pN, const char ***pazValue, const char ***pazColName) { db_stmt_p stmt = vmx; int rc, busyc = 0; csync_debug(4, "Trying to fetch a row from the database.\n"); while (1) { rc = db_stmt_next(stmt); if ( rc != DB_BUSY ) break; if (busyc++ > get_dblock_timeout()) { db = 0; csync_fatal(DEADLOCK_MESSAGE); } csync_debug(2, "Database is busy, sleeping a sec.\n"); sleep(1); } if ( rc != DB_OK && rc != DB_ROW && rc != DB_DONE && err ) csync_fatal("Database Error: %s [%d]: %s\n", err, rc, db_errmsg(db)); return rc == DB_ROW; }
void* csync_db_begin(const char *err, const char *fmt, ...) { db_stmt_p stmt = NULL; char *sql; va_list ap; int rc, busyc = 0; char *ppTail; va_start(ap, fmt); VASPRINTF(&sql, fmt, ap); va_end(ap); in_sql_query++; csync_db_maybegin(); csync_debug(2, "SQL: %s\n", sql); while (1) { rc = db_prepare_stmt(db, sql, &stmt, &ppTail); if ( rc != DB_BUSY ) break; if (busyc++ > get_dblock_timeout()) { db = 0; csync_fatal(DEADLOCK_MESSAGE); } csync_debug(2, "Database is busy, sleeping a sec.\n"); sleep(1); } if ( rc != DB_OK && err ) csync_fatal("Database Error: %s [%d]: %s on executing %s\n", err, rc, db_errmsg(db), sql); free(sql); return stmt; }
int ListMgr_Insert(lmgr_t *p_mgr, entry_id_t *p_id, attr_set_t *p_info, int update_if_exists) { int rc; char buff[4096]; /* retry the whole transaction when the error is retryable */ retry: rc = lmgr_begin(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) return rc; rc = listmgr_batch_insert_no_tx(p_mgr, &p_id, &p_info, 1, update_if_exists); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) { lmgr_rollback(p_mgr); DisplayLog(LVL_CRIT, LISTMGR_TAG, "DB query failed in %s line %d: code=%d: %s", __FUNCTION__, __LINE__, rc, db_errmsg(&p_mgr->conn, buff, 4096)); return rc; } rc = lmgr_commit(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; /* success, count it */ if (!rc) p_mgr->nbop[OPIDX_INSERT]++; return rc; }
/** * Insert a batch of entries into the database. * All entries must have the same attr mask. */ int ListMgr_BatchInsert(lmgr_t * p_mgr, entry_id_t ** p_ids, attr_set_t ** p_attrs, unsigned int count, int update_if_exists) { int rc; char buff[4096]; if (count == 0) return DB_SUCCESS; else if (p_ids == NULL || p_attrs == NULL) RBH_BUG("NULL pointer argument"); /* read only fields in info mask? */ if (readonly_attr_set & p_attrs[0]->attr_mask) { DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Error: trying to insert read only values: attr_mask=%#x", readonly_attr_set & p_attrs[0]->attr_mask); return DB_INVALID_ARG; } /* retry the whole transaction when the error is retryable */ retry: /* We want insert operation set to be atomic */ rc = lmgr_begin(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) return rc; rc = listmgr_batch_insert_no_tx(p_mgr, p_ids, p_attrs, count, update_if_exists); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; else if (rc) { lmgr_rollback(p_mgr); DisplayLog(LVL_CRIT, LISTMGR_TAG, "DB query failed in %s line %d: code=%d: %s", __FUNCTION__, __LINE__, rc, db_errmsg(&p_mgr->conn, buff, 4096)); return rc; } rc = lmgr_commit(p_mgr); if (lmgr_delayed_retry(p_mgr, rc)) goto retry; /* success, count it */ if (!rc) { if (update_if_exists) p_mgr->nbop[OPIDX_UPDATE] += count; else p_mgr->nbop[OPIDX_INSERT] += count; } return rc; }
int insert_stripe_info( lmgr_t * p_mgr, PK_ARG_T pk, int validator, const stripe_info_t * p_stripe, const stripe_items_t * p_items, int update_if_exists ) { int i, rc; int created = FALSE; if ( p_stripe == NULL ) return DB_INVALID_ARG; do { char short_query[4096]; /* First insert info into STRIPE_INFO_TABLE, * so if a file is already present with the same id, * we will remove its previous stripe info */ sprintf( short_query, "INSERT INTO " STRIPE_INFO_TABLE "(id,validator, stripe_count,stripe_size,pool_name) " "VALUES ("DPK",%u,%u,%u,'%s')", pk, validator, p_stripe->stripe_count, ( unsigned int ) p_stripe->stripe_size, p_stripe->pool_name ); if ( update_if_exists ) rc = db_exec_sql_quiet( &p_mgr->conn, short_query, NULL ); else rc = db_exec_sql( &p_mgr->conn, short_query, NULL ); if ( rc == 0 ) { created = TRUE; } else if ( (rc == DB_ALREADY_EXISTS) && update_if_exists ) { /* remove previous stripe info */ DisplayLog( LVL_EVENT, LISTMGR_TAG, "A stripe info already exists with this identifier, removing it" ); rc = delete_stipe_info( p_mgr, pk ); } if ( rc != 0 ) { DisplayLog( LVL_CRIT, LISTMGR_TAG, "DB query failed in %s line %d: code=%d: %s", __FUNCTION__, __LINE__, rc, db_errmsg( &p_mgr->conn, short_query, 4096 ) ); return rc; } } while ( !created ); /* retry loop in case a similar entry already exists */ /* then insert stripe items */ if ( (p_items != NULL) && (p_items->count > 0) ) { ssize_t len; unsigned int est_len; char *query = NULL; /* estimate query size = fix part + stripe_count * ( 4 + pklen + ost_idx_len ) * = ~64(oversize to 128) + stripe_count * 4 + 128 */ est_len = 128 + p_items->count * 128; DisplayLog( LVL_FULL, LISTMGR_TAG, "Estimated query size for %u stripe = %u", p_items->count, est_len ); query = MemAlloc(est_len); if (query == NULL) { DisplayLog( LVL_CRIT, LISTMGR_TAG, "Not enough memory to build SQL query (length = %u)", est_len ); return DB_NO_MEMORY; } strcpy( query, "INSERT INTO " STRIPE_ITEMS_TABLE "(id, storage_item) VALUES " ); len = strlen( query ); /* first stripe item */ len += snprintf( query + len, est_len - len, "("DPK",%u)", pk, p_items->stripe_units[0] ); /* next items */ for ( i = 1; i < p_items->count; i++ ) { len += snprintf( query + len, est_len - len, ",("DPK",%u)", pk, p_items->stripe_units[i] ); if ( len >= est_len ) { DisplayLog( LVL_CRIT, LISTMGR_TAG, "Error in %s(): query too long (>%u bytes long), stripe_count=%d", __FUNCTION__, est_len, p_items->count ); MemFree( query ); return DB_BUFFER_TOO_SMALL; } } rc = db_exec_sql( &p_mgr->conn, query, NULL ); if ( rc ) { DisplayLog( LVL_CRIT, LISTMGR_TAG, "DB query failed in %s line %d: code=%d: %s", __FUNCTION__, __LINE__, rc, db_errmsg( &p_mgr->conn, query, 4096 ) ); MemFree( query ); return rc; } MemFree( query ); } return 0; }
void csync_db_open(const char *file) { int rc = db_open(file, db_type, &db); if ( rc != DB_OK ) csync_fatal("Can't open database: %s\n", file); db_set_logger(db, csync_debug); /* ignore errors on table creation */ in_sql_query++; if (db_schema_version(db) < DB_SCHEMA_VERSION) if (db_upgrade_to_schema(db, DB_SCHEMA_VERSION) != DB_OK) csync_fatal("Cannot create database tables (version requested = %d): %s\n", DB_SCHEMA_VERSION, db_errmsg(db)); if (!db_sync_mode) db_exec(db, "PRAGMA synchronous = OFF"); in_sql_query--; // return db; }