diff --git a/src/plugins/accounting_storage/mysql/as_mysql_resource.c b/src/plugins/accounting_storage/mysql/as_mysql_resource.c
index 3c817e9a69b60c6d1e51dc0c5f10d80535a0c7d6..fcf1323ed64484bc3ca674edf8d853e4ea17f68c 100644
--- a/src/plugins/accounting_storage/mysql/as_mysql_resource.c
+++ b/src/plugins/accounting_storage/mysql/as_mysql_resource.c
@@ -43,366 +43,320 @@
 #include "as_mysql_wckey.h"
 #include "src/common/node_select.h"
 
-static int _setup_ser_res_limits(slurmdb_ser_res_rec_t *ser_res,
-				 char **cols, char **vals,
-				 char **extra, bool for_add)
+static void _setup_res_cond(slurmdb_res_cond_t *res_cond,
+			    char **extra)
 {
-	if (!ser_res)
-		return SLURM_ERROR;
-
-	if (for_add) {
-		/* If we are adding we should make sure we don't get
-		   old residue sitting around from a former life.
-		*/
-		if (!ser_res->description)
-			ser_res->description = xstrdup("");
-		if (!ser_res->name)
-			ser_res->name = xstrdup("");
-		if (!ser_res->manager)
-			ser_res->manager = xstrdup("");
-		if (!ser_res->server)
-			ser_res->server = xstrdup("");
-		if (ser_res->count == NO_VAL)
-			ser_res->count = 0;
-		if (!ser_res->type)
-			ser_res->type = SLURMDB_RESOURCE_LICENSE;
-	}
-
-	if (ser_res->description) {
-		xstrcat(*cols, ", description");
-		xstrfmtcat(*vals, ", '%s'", ser_res->description);
-		xstrfmtcat(*extra, ", description='%s'",
-			   ser_res->description);
-	}
-
-	if (ser_res->manager) {
-		xstrcat(*cols, ", manager");
-		xstrfmtcat(*vals, ", '%s'", ser_res->manager);
-		xstrfmtcat(*extra, ", manager='%s'",
-			   ser_res->manager);
-	}
-
-	if (ser_res->server) {
-		xstrcat(*cols, ", server");
-		xstrfmtcat(*vals, ", '%s'", ser_res->server);
-		xstrfmtcat(*extra, ", server='%s'",
-			   ser_res->server);
-	}
-	xstrcat(*cols, ", count");
-	xstrfmtcat(*vals, ", %u", ser_res->count);
-	xstrfmtcat(*extra, ", count=%u", ser_res->count);
-
-	xstrcat(*cols, ", type");
-	xstrfmtcat(*vals, ", %u", ser_res->type);
-	xstrfmtcat(*extra, ", type=%u", ser_res->type);
-
-	return SLURM_SUCCESS;
-}
-
-static int _populate_cluster_name_list(List new_name_list,
-				       mysql_conn_t *mysql_conn, uid_t uid)
-{
-	List cluster_list = NULL;
+	int set = 0;
 	ListIterator itr = NULL;
-	char *cluster_name;
-	slurmdb_cluster_rec_t *cluster = NULL;
+	char *object = NULL;
 
-	cluster_list = acct_storage_g_get_clusters(mysql_conn, uid, NULL);
-	if (!cluster_list) {
-		fprintf(stderr,
-			" Error obtaining cluster records.\n");
-		return SLURM_ERROR;
+	if (!res_cond) {
+		xstrcat(*extra, "where t1.deleted=0");
+		return;
 	}
-	itr = list_iterator_create(cluster_list);
-	while ((cluster = list_next(itr))) {
-		cluster_name = xstrdup(cluster->name);
-		list_append(new_name_list, cluster_name);
-	}
-	list_iterator_destroy(itr);
-	list_destroy(cluster_list);
-	return SLURM_SUCCESS;
-}
-
-extern int as_mysql_add_ser_res(mysql_conn_t *mysql_conn, uint32_t uid,
-				List ser_res_list)
-{
-	ListIterator itr = NULL;
-	int rc = SLURM_SUCCESS;
-	slurmdb_ser_res_rec_t *object = NULL;
-	char *cols = NULL, *extra = NULL, *vals = NULL, *query = NULL,
-		*tmp_extra = NULL;
-	time_t now = time(NULL);
-	char *user_name = NULL;
-	int affect_rows = 0;
-	int added = 0;
-
-	if (check_connection(mysql_conn) != SLURM_SUCCESS)
-		return ESLURM_DB_CONNECTION;
-
-	user_name = uid_to_string((uid_t) uid);
-	itr = list_iterator_create(ser_res_list);
-	while ((object = list_next(itr))) {
-		if (!object->name || !object->name[0]) {
-			error("We need a server resource name to add.");
-			rc = SLURM_ERROR;
-			continue;
-		}
-		xstrcat(cols, "creation_time, mod_time, name");
-		xstrfmtcat(vals, "%ld, %ld, '%s'",
-			   now, now, object->name);
-		xstrfmtcat(extra, ", mod_time=%ld", now);
-
-		_setup_ser_res_limits(object, &cols, &vals,
-				      &extra, 1);
-
-		xstrfmtcat(query,
-			   "insert into %s (%s) values (%s) "
-			   "on duplicate key update deleted=0, "
-			   "id=LAST_INSERT_ID(id)%s;",
-			   ser_res_table, cols, vals, extra);
-
-
-		debug3("%d(%s:%d) query\n%s",
-		       mysql_conn->conn, THIS_FILE, __LINE__, query);
-		object->id = mysql_db_insert_ret_id(mysql_conn, query);
-		xfree(query);
-		if (!object->id) {
-			error("Couldn't add server resource %s", object->name);
-			added=0;
-			xfree(cols);
-			xfree(extra);
-			xfree(vals);
-			break;
-		}
-
-		affect_rows = last_affected_rows(mysql_conn);
-
-		if (!affect_rows) {
-			debug2("nothing changed %d", affect_rows);
-			xfree(cols);
-			xfree(extra);
-			xfree(vals);
-			continue;
-		}
 
-		/* we always have a ', ' as the first 2 chars */
-		tmp_extra = slurm_add_slash_to_quotes(extra+2);
-
-		xstrfmtcat(query,
-			   "insert into %s "
-			   "(timestamp, action, name, actor, info) "
-			   "values (%ld, %u, '%s', '%s', '%s');",
-			   txn_table,
-			   now, DBD_ADD_SER_RES, object->name, user_name,
-			   tmp_extra);
+	if (res_cond->with_deleted)
+		xstrcat(*extra, "where (t1.deleted=0 || t1.deleted=1)");
+	else
+		xstrcat(*extra, "where t1.deleted=0");
 
-		xfree(tmp_extra);
-		xfree(cols);
-		xfree(extra);
-		xfree(vals);
-		debug3("%d(%s:%d) query\n%s",
-		       mysql_conn->conn, THIS_FILE, __LINE__, query);
-		rc = mysql_db_query(mysql_conn, query);
-		xfree(query);
-		if (rc != SLURM_SUCCESS) {
-			error("Couldn't add txn");
-		} else {
-			if (addto_update_list(mysql_conn->update_list,
-					      SLURMDB_ADD_SER_RES,
-					      object) == SLURM_SUCCESS) {
-				list_remove(itr);
-				added++;
-			}
+	if (res_cond->description_list
+	    && list_count(res_cond->description_list)) {
+		set = 0;
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->description_list);
+		while ((object = list_next(itr))) {
+			if (set)
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "description='%s'", object);
+			set = 1;
 		}
-
+		list_iterator_destroy(itr);
+		xstrcat(*extra, ")");
 	}
-	list_iterator_destroy(itr);
-	xfree(user_name);
 
-	if (!added) {
-		reset_mysql_conn(mysql_conn);
+	if (!(res_cond->flags & SLURMDB_RES_FLAG_NOTSET)) {
+		xstrfmtcat(*extra, " && (flags & %u)",
+			   res_cond->flags & SLURMDB_RES_FLAG_BASE);
 	}
 
-	return rc;
-}
-
-extern List as_mysql_get_ser_res(mysql_conn_t *mysql_conn, uid_t uid,
-				 slurmdb_ser_res_cond_t *ser_res_cond)
-{
-	char *query = NULL;
-	char *extra = NULL;
-	char *tmp = NULL;
-	List ser_res_list = NULL;
-	ListIterator itr = NULL;
-	char *object = NULL;
-	int set = 0;
-	int i=0;
-	MYSQL_RES *result = NULL;
-	MYSQL_ROW row;
-
-	/* if this changes you will need to edit the corresponding enum */
-	char *ser_res_req_inx[] = {
-		"name",
-		"description",
-		"id",
-		"manager",
-		"server",
-		"count",
-		"type",
-	};
-	enum {
-		SER_RES_REQ_NAME,
-		SER_RES_REQ_DESC,
-		SER_RES_REQ_ID,
-		SER_RES_REQ_MANAGER,
-		SER_RES_REQ_SERVER,
-		SER_RES_REQ_COUNT,
-		SER_RES_REQ_TYPE,
-		SER_RES_REQ_NUMBER,
-	};
-
-	if (check_connection(mysql_conn) != SLURM_SUCCESS)
-		return NULL;
-
-	if (!ser_res_cond) {
-		xstrcat(extra, "where deleted=0");
-		goto empty;
+	if (res_cond->id_list
+	    && list_count(res_cond->id_list)) {
+		set = 0;
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->id_list);
+		while ((object = list_next(itr))) {
+			if (set)
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "id='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(*extra, ")");
 	}
 
-	if (ser_res_cond->with_deleted)
-		xstrcat(extra, "where (deleted=0 || deleted=1)");
-	else
-		xstrcat(extra, "where deleted=0");
-
-
-	if (ser_res_cond->description_list
-	    && list_count(ser_res_cond->description_list)) {
+	if (res_cond->manager_list
+	    && list_count(res_cond->manager_list)) {
 		set = 0;
-		xstrcat(extra, " && (");
-		itr = list_iterator_create(ser_res_cond->description_list);
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->manager_list);
 		while ((object = list_next(itr))) {
 			if (set)
-				xstrcat(extra, " || ");
-			xstrfmtcat(extra, "description='%s'", object);
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "manager='%s'", object);
 			set = 1;
 		}
 		list_iterator_destroy(itr);
-		xstrcat(extra, ")");
+		xstrcat(*extra, ")");
 	}
 
-	if (ser_res_cond->id_list
-	    && list_count(ser_res_cond->id_list)) {
+	if (res_cond->name_list
+	    && list_count(res_cond->name_list)) {
 		set = 0;
-		xstrcat(extra, " && (");
-		itr = list_iterator_create(ser_res_cond->id_list);
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->name_list);
 		while ((object = list_next(itr))) {
 			if (set)
-				xstrcat(extra, " || ");
-			xstrfmtcat(extra, "id='%s'", object);
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "name='%s'", object);
 			set = 1;
 		}
 		list_iterator_destroy(itr);
-		xstrcat(extra, ")");
+		xstrcat(*extra, ")");
 	}
 
-	if (ser_res_cond->name_list
-	    && list_count(ser_res_cond->name_list)) {
+	if (res_cond->server_list
+	    && list_count(res_cond->server_list)) {
 		set = 0;
-		xstrcat(extra, " && (");
-		itr = list_iterator_create(ser_res_cond->name_list);
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->server_list);
 		while ((object = list_next(itr))) {
 			if (set)
-				xstrcat(extra, " || ");
-			xstrfmtcat(extra, "name='%s'", object);
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "server='%s'", object);
 			set = 1;
 		}
 		list_iterator_destroy(itr);
-		xstrcat(extra, ")");
+		xstrcat(*extra, ")");
 	}
 
-	if (ser_res_cond->manager_list
-	    && list_count(ser_res_cond->manager_list)) {
+	if (res_cond->type_list
+	    && list_count(res_cond->type_list)) {
 		set = 0;
-		xstrcat(extra, " && (");
-		itr = list_iterator_create(ser_res_cond->manager_list);
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->type_list);
 		while ((object = list_next(itr))) {
 			if (set)
-				xstrcat(extra, " || ");
-			xstrfmtcat(extra, "manager='%s'", object);
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "type='%s'", object);
 			set = 1;
 		}
 		list_iterator_destroy(itr);
-		xstrcat(extra, ")");
+		xstrcat(*extra, ")");
 	}
-	if (ser_res_cond->server_list
-	    && list_count(ser_res_cond->server_list)) {
+}
+
+static int _setup_clus_res_cond(slurmdb_res_cond_t *res_cond, char **extra)
+{
+	ListIterator itr;
+	bool set = 0;
+	char *tmp = NULL;
+	int query_clusters = 0;
+
+	if (!res_cond) {
+		xstrfmtcat(*extra, "%st2.deleted=0", *extra ? " && " : "");
+		return SLURM_SUCCESS;
+	}
+
+	if (res_cond->with_deleted)
+		xstrfmtcat(*extra, "%s(t2.deleted=0 || t2.deleted=1)",
+			   *extra ? " && " : "");
+	else
+		xstrfmtcat(*extra, "%st2.deleted=0", *extra ? " && " : "");
+
+	if (res_cond->cluster_list && list_count(res_cond->cluster_list)) {
 		set = 0;
-		xstrcat(extra, " && (");
-		itr = list_iterator_create(ser_res_cond->server_list);
-		while ((object = list_next(itr))) {
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->cluster_list);
+		while ((tmp = list_next(itr))) {
 			if (set)
-				xstrcat(extra, " || ");
-			xstrfmtcat(extra, "server='%s'", object);
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "t2.cluster='%s'", tmp);
 			set = 1;
 		}
 		list_iterator_destroy(itr);
-		xstrcat(extra, ")");
+		xstrcat(*extra, ")");
+		query_clusters += set;
 	}
 
-empty:
+	if (res_cond->percent_list && list_count(res_cond->percent_list)) {
+		set = 0;
+		xstrcat(*extra, " && (");
+		itr = list_iterator_create(res_cond->percent_list);
+		while ((tmp = list_next(itr))) {
+			if (set)
+				xstrcat(*extra, " || ");
+			xstrfmtcat(*extra, "t2.percent_allowed='%s'", tmp);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(*extra, ")");
+		query_clusters += set;
+	}
 
-	xfree(tmp);
-	xstrfmtcat(tmp, "%s", ser_res_req_inx[i]);
-	for(i=1; i<SER_RES_REQ_NUMBER; i++) {
-		xstrfmtcat(tmp, ", %s", ser_res_req_inx[i]);
+	return query_clusters;
+}
+
+static int _setup_res_limits(slurmdb_res_rec_t *res,
+			     char **cols, char **vals,
+			     char **extra, bool for_add, bool *send_update)
+{
+	if (!res)
+		return SLURM_ERROR;
+
+	if (for_add) {
+		/* If we are adding we should make sure we don't get
+		   old residue sitting around from a former life.
+		*/
+		if (res->count == NO_VAL)
+			res->count = 0;
+		if (res->type == SLURMDB_RESOURCE_NOTSET)
+			res->type = SLURMDB_RESOURCE_LICENSE;
 	}
 
-	query = xstrdup_printf("select %s from %s %s", tmp,
-			       ser_res_table, extra);
-	xfree(tmp);
-	xfree(extra);
+	if (res->count != NO_VAL) {
+		if (cols)
+			xstrcat(*cols, ", count");
+		xstrfmtcat(*vals, ", %u", res->count);
+		xstrfmtcat(*extra, ", count=%u", res->count);
+		if (send_update)
+			*send_update = 1;
+	}
 
-	debug3("%d(%s:%d) query\n%s",
-	       mysql_conn->conn, THIS_FILE, __LINE__, query);
-	if (!(result = mysql_db_query_ret(
-		      mysql_conn, query, 0))) {
-		xfree(query);
-		return NULL;
+	if (res->description) {
+		if (cols)
+			xstrcat(*cols, ", description");
+		xstrfmtcat(*vals, ", '%s'", res->description);
+		xstrfmtcat(*extra, ", description='%s'",
+			   res->description);
 	}
-	xfree(query);
 
-	ser_res_list = list_create(slurmdb_destroy_ser_res_rec);
+	if (!(res->flags & SLURMDB_RES_FLAG_NOTSET)) {
+		uint32_t base_flags = (res->flags & SLURMDB_RES_FLAG_BASE);
+		if (cols)
+			xstrcat(*cols, ", flags");
+		if (res->flags & SLURMDB_RES_FLAG_REMOVE) {
+			xstrfmtcat(*vals, ", (VALUES(flags) & ~%u)'",
+				   base_flags);
+			xstrfmtcat(*extra, ", flags=(flags & ~%u)",
+				   base_flags);
+		} else if (res->flags & SLURMDB_RES_FLAG_ADD) {
+			xstrfmtcat(*vals, ", (VALUES(flags) | %u)'",
+				   base_flags);
+			xstrfmtcat(*extra, ", flags=(flags | %u)",
+				   base_flags);
+		} else {
+			xstrfmtcat(*vals, ", '%u'", base_flags);
+			xstrfmtcat(*extra, ", flags=%u", base_flags);
+		}
+		if (send_update)
+			*send_update = 1;
+	}
 
-	while ((row = mysql_fetch_row(result))) {
-		slurmdb_ser_res_rec_t *ser_res =
-			xmalloc(sizeof(slurmdb_ser_res_rec_t));
-		slurmdb_init_ser_res_rec(ser_res, 0);
+	if (res->manager) {
+		if (cols)
+			xstrcat(*cols, ", manager");
+		xstrfmtcat(*vals, ", '%s'", res->manager);
+		xstrfmtcat(*extra, ", manager='%s'", res->manager);
+	}
 
-		if (row[SER_RES_REQ_DESC] && row[SER_RES_REQ_DESC][0])
-			ser_res->description = xstrdup(row[SER_RES_REQ_DESC]);
+	if (res->type != SLURMDB_RESOURCE_NOTSET) {
+		if (cols)
+			xstrcat(*cols, ", type");
+		xstrfmtcat(*vals, ", %u", res->type);
+		xstrfmtcat(*extra, ", type=%u", res->type);
+		if (send_update)
+			*send_update = 1;
+	}
 
-		ser_res->id = slurm_atoul(row[SER_RES_REQ_ID]);
+	return SLURM_SUCCESS;
+}
 
-		if (row[SER_RES_REQ_NAME] && row[SER_RES_REQ_NAME][0])
-			ser_res->name = xstrdup(row[SER_RES_REQ_NAME]);
+static int _fill_in_res_rec(mysql_conn_t *mysql_conn, slurmdb_res_rec_t *res)
+{
+	int rc = SLURM_SUCCESS, i;
+	char *query = NULL;
+	MYSQL_RES *result = NULL;
+	MYSQL_ROW row;
+	char *tmp = NULL;
 
-		if (row[SER_RES_REQ_MANAGER] && row[SER_RES_REQ_MANAGER][0])
-			ser_res->manager = xstrdup(row[SER_RES_REQ_MANAGER]);
+	/* if this changes you will need to edit the corresponding enum */
+	char *res_req_inx[] = {
+		"count",
+		"flags",
+		"id",
+		"name",
+		"server",
+		"type",
+	};
+	enum {
+		RES_REQ_COUNT,
+		RES_REQ_FLAGS,
+		RES_REQ_ID,
+		RES_REQ_NAME,
+		RES_REQ_SERVER,
+		RES_REQ_TYPE,
+		RES_REQ_NUMBER,
+	};
 
-		if (row[SER_RES_REQ_SERVER] && row[SER_RES_REQ_SERVER][0])
-			ser_res->server = xstrdup(row[SER_RES_REQ_SERVER]);
+	xassert(res);
+	xassert(res->id != NO_VAL);
 
-		if (row[SER_RES_REQ_COUNT])
-			ser_res->count =
-				slurm_atoul(row[SER_RES_REQ_COUNT]);
-		if (row[SER_RES_REQ_TYPE])
-			ser_res->type =
-				slurm_atoul(row[SER_RES_REQ_TYPE]);
-		list_append(ser_res_list, ser_res);
+	xfree(tmp);
+	xstrfmtcat(tmp, "%s", res_req_inx[0]);
+	for (i=1; i<RES_REQ_NUMBER; i++) {
+		xstrfmtcat(tmp, ", %s", res_req_inx[i]);
+	}
+
+	query = xstrdup_printf("select distinct %s from %s where id=%u;",
+			       tmp, res_table, res->id);
+
+	xfree(tmp);
+
+	debug3("%d(%s:%d) query\n%s",
+	       mysql_conn->conn, THIS_FILE, __LINE__, query);
+	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
+		xfree(query);
+		return SLURM_ERROR;
 	}
+	xfree(query);
+
+	if (!(row = mysql_fetch_row(result))) {
+		error("Resource id %u is not known on the system", res->id);
+		return SLURM_ERROR;
+	}
+
+	/* Overwrite everything just to make sure the client side
+	   didn't try anything tricky.
+	*/
+	if (row[RES_REQ_COUNT] && row[RES_REQ_COUNT][0])
+		res->count = slurm_atoul(row[RES_REQ_COUNT]);
+	if (row[RES_REQ_FLAGS] && row[RES_REQ_FLAGS][0])
+		res->flags = slurm_atoul(row[RES_REQ_FLAGS]);
+	if (row[RES_REQ_NAME] && row[RES_REQ_NAME][0]) {
+		xfree(res->name);
+		res->name = xstrdup(row[RES_REQ_NAME]);
+	}
+	if (row[RES_REQ_SERVER] && row[RES_REQ_SERVER][0]) {
+		xfree(res->server);
+		res->server = xstrdup(row[RES_REQ_SERVER]);
+	}
+	if (row[RES_REQ_TYPE] && row[RES_REQ_TYPE][0])
+		res->type = slurm_atoul(row[RES_REQ_TYPE]);
+
 	mysql_free_result(result);
 
-	return ser_res_list;
+	return rc;
 }
 
 extern List as_mysql_remove_ser_res(mysql_conn_t *mysql_conn, uint32_t uid,