2013-12-10
2013-12-10 11:22:02 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
e9753c98de391cc3c7920171d6498bd2a97d65f2
(67 lines)
(+60/-7)
[
Show
| Annotate
]
Branch: 5.4
ImageCache: Allow for larger images.
Changes the data field from a mediumblob (max 16MB) to a largeblob (max 4GB).
Updates large fields in chunks of 8MB.
Fixes some of [bug 6938 (#6938)].
4006: Inside #if defined(ARG_CACHE_DEBUG)
#ifdef ARG_CACHE_DEBUG
werror("Replacing entry for %O\n", id );
#endif
- QUERY("REPLACE INTO "+name+
+ if (sizeof(data) <= 8*1024*1024) {
+ // Should fit in the 16 MB query limit without problem.
+ // Albeit it might trigger a slow query entry for large
+ // entries.
+ QUERY("REPLACE INTO " + name +
" (id,size,atime,meta,data) VALUES"
" (%s,%d,UNIX_TIMESTAMP()," MYSQL__BINARY "%s," MYSQL__BINARY "%s)",
id, strlen(data)+strlen(meta_data), meta_data, data );
-
+ } else {
+ // We need to perform multiple queries.
#ifdef ARG_CACHE_DEBUG
-
+ werror("Writing %d bytes of padding for %s.\n", sizeof(data), id);
+ #endif
+ array(string) a = data/(8.0*1024*1024);
+ // NB: We clear the meta field to ensure that the entry
+ // is invalid while we perform the insert.
+ QUERY("REPLACE INTO " + name +
+ " (id,size,atime,meta,data) VALUES"
+ " (%s,%d,UNIX_TIMESTAMP(),'',SPACE(%d))",
+ id, strlen(data)+strlen(meta_data), sizeof(data));
+ int pos;
+ foreach(a, string frag) {
+ #ifdef ARG_CACHE_DEBUG
+ werror("Writing fragment at position %d for %s.\n", pos, id);
+ #endif
+ QUERY("UPDATE " + name +
+ " SET data = INSERT(data, %d, %d, "MYSQL__BINARY "%s)"
+ " WHERE id = %s",
+ pos+1, sizeof(frag), frag, id);
+ pos += sizeof(frag);
+ }
+ /* Set the meta data field to a valid value to enable the entry. */
+ #ifdef ARG_CACHE_DEBUG
+ werror("Writing metadata for %s.\n", id);
+ #endif
+ QUERY("UPDATE " + name +
+ " SET meta = " MYSQL__BINARY "%s"
+ " WHERE id = %s",
+ meta_data, id);
+ }
+ #ifdef ARG_CACHE_DEBUG
array(mapping(string:string)) q =
QUERY("SELECT meta, data FROM " + name +
" WHERE id = %s", id);
4023: Inside #if defined(ARG_CACHE_DEBUG)
meta_data, q[0]->meta);
}
if (q[0]->data != data) {
- werror("Data differs: %O != %O\n",
- data, q[0]->data);
+ string d = q[0]->data;
+ int i;
+ int cnt;
+ for (i = 0; i < sizeof(data); i++) {
+ if (data[i] == d[i]) continue;
+ werror("Data differs at offset %d: %d != %d\n",
+ i, data[i], d[i]);
+ if (cnt++ > 10) break;
}
}
-
+ }
#endif
}
4458:
"uid CHAR(32) NOT NULL DEFAULT '', "
"atime INT UNSIGNED NOT NULL DEFAULT 0,"
"meta MEDIUMBLOB NOT NULL DEFAULT '',"
- "data MEDIUMBLOB NOT NULL DEFAULT '',"
+ "data LARGEBLOB NOT NULL DEFAULT '',"
"INDEX atime_id (atime, id)"
")" );
}
4479:
QUERY("DROP INDEX atime ON " + name);
report_debug("complete. [%f s]\n", (gethrtime() - start_time)/1000000.0);
}
+ res = QUERY("SHOW COLUMNS FROM " + name + " WHERE Field = 'data'");
+ if (lowercase(res[0]->Type) != "longblob") {
+ report_debug("Updating " + name + " image cache: "
+ "Increasing maximum blob size...");
+ start_time = gethrtime();
+ QUERY("ALTER TABLE " + name +
+ "MODIFY COLUMN data LONGBLOB NOT NULL DEFAULT ''");
+ report_debug("complete. [%f s]\n", (gethrtime() - start_time)/1000000.0);
}
-
+ }
Sql.Sql get_db()
{