Cassandra Commit log ideal size and default size clarification - configuration

From the docs it is given
commitlog_total_space_in_mb
(Default: 32MB for 32-bit JVMs, 8192MB for 64-bit JVMs)note Total space used for commitlogs. If the used space goes above this value, Cassandra rounds up to the next nearest segment multiple and flushes memtables to disk for the oldest commitlog segments, removing those log segments. This reduces the amount of data to replay on start-up, and prevents infrequently-updated tables from indefinitely keeping commitlog segments. A small total commitlog space tends to cause more flush activity on less-active tables.
And from the Cassandra.yaml it is specified :
Total space to use for commit logs on disk.
If space gets above this value, Cassandra will flush every dirty CF
in the oldest segment and remove it. So a small total commitlog space
will tend to cause more flush activity on less-active columnfamilies.
The default value is the smaller of 8192, and 1/4 of the total space
of the commitlog volume.
commitlog_total_space_in_mb: 8192
The query i have is What does the following statement mean :
The default value is the smaller of 8192, and 1/4 of the total space
of the commitlog volume.
I have my commitlog in the same hard drive but different drive
I have allocated the volume of commit log to 70 GB. Should I reduce it to 8gb or should i reduce it to 32 GB as 1/4 of the volume space confuses me to consider that partition space.
I have the default value for commitlog_total_space_in_mb , so what should be the ideal commit log partition size ??
P.s : I know that these 2 should be on different drives for better performance.

As for your first question about Cassandra.yaml statement - the commit log size will be:
Min(8GB, 0.25*total_disk_size)
In your case since you have allocated 70 GB, the commit log size will be 8 GB.
You can avoid those calculation be setting the size at Cassandra.yaml
As for your second question, what is the optimal size, from my testing when setting the commit log directory under 8GB you will get a warning for insufficient disk size for it, so set it more than 8GB and remember that you can always increase that size.

Related

Random InnoDB INSERTs super slow

I have the following INSERT statement:
cursor.execute('''UPDATE alg SET size=%(size)s, path=%(path)s,
last_modified=%(last_modified)s, search_terms=%
WHERE objectID=%(objectID)s''', data)
It is indexed and usually takes 1/1000th of a second to do. However, once every 200 INSERTs or so, it takes a super long time. Here's an example of it timed --
453
0.000407934188843
454
0.29783987999 <-- this one
455
0.000342130661011
456
0.000318765640259
457
0.000240087509155
The column is indexed and it is using InnoDB. Any idea what the issue might be? It also seems random in that if I run it over and over, different objects cause the INSERTs to be slow -- it's not tied to any particular object.
Also note that I do not have this issue on MyISAM.
You likely have default innodb_log_file_size, which id 5 Megabytes. Set this in your cnf file to be the minimum of 128M or 25% of your innodb_buffer_pool_size. You'll want the buffer pool to be as large as possible for your system. If it's a dedicated mysql server then 70-80% of system RAM would not be unreasonable (leaving some for OS page cache).
Setting the log file size larger will space out times things need to be flushed to tables. Setting it too large will increase crash recovery times on restarts.
Also be sure to set innodb_flush_method=O_DIRECT to avoid OS level page caching.

Is the size of the undo log in InnoDB fixed or does it vary by the size of the iblogfiles? What about redo?

Jeremy Cole's presentation InnoDB: A journey to the core II seems to indicate that there are 128 slots and each slot can have 1024 transactions. So I make that a hard limit of 2^17 updates that are logged in the log files.
I'm looking for a way to rotate out updates from the undo and redo logs in ibdata1 and ib_logfile[01] files. If I can determine - either statically, or dynamically from the configuration - what the maximum number of undo and redo log entries are, then I can force a number of updates into the system that will rotate out the data I'm trying to expunge from the files.
If Jeremy Cole can be taken literally, 131,072 updates should rotate out the original value of a column in a record. Or is it more complicated than that?
The answer is, that it is indeed "more complicated than that", unfortunately. First, some clarifications.
Redo Log
The "redo log" is configurable via two parameters:
innodb_log_file_size — controls the size of each log file created, in bytes.
innodb_log_files_in_group — controls the number of log files to create, each of innodb_log_file_size bytes.
This makes the "log space" approximately innodb_log_file_size * innodb_log_files_in_group in size, and you could see, for instance 256 MiB * 2 for a total of approximately 512 MiB of log file.
This redo log space completely allocated at first startup (all files are pre-created at their full size) and is used sequentially from start to finish. Usage of it "wraps around" from the end of the last file back to the beginning of the first, like a circular buffer. Each time a database modification occurs, "log records" describing that modification are written to the redo log. The size of each of these log records is variable.
Undo Log
The "undo log" is not really configurable and is not really a "log" at all, in the traditional sense. The undo log exists as pages allocated inside the InnoDB system tablespace (usually named ibdata1) and consumes its space there. It is not pre-allocated or of a fixed size; it grows on demand. Each time a record is modified in InnoDB, the previous version of that record's data is copied into some undo log page before the records in the original page are allowed to be modified.
The undo log pages are each part of a chain of undo log pages which form an undo segment, and consume a "slot" in a rollback segment, which has 1024 slots. There are by default now 128 rollback segments. This is where the mentioned limit of 128 * 1024 (or 2^17) active transactions comes from. Each active transaction consumes a slot in a rollback segment, so the maximum number of active, concurrent transactions is now by default 128 * 1024 = ~131,072 (however some of those slots are consumed by background tasks, occasionally).
On expunging old data
The original question was really about how to ensure that data is expunged from the system when the administrator desires it so. This is both very easy and very hard, actually.
Expunging the data from the redo log merely requires that enough redo log space is consumed to completely cycle the redo log. This can be via many small transactions or a few large transactions. Transactions can be executed until the current LSN has advanced by the number of bytes in the log (since LSN is an analog for log bytes, although not perfectly so).
Expunging data from the undo log is nearly impossible, though, and difficult to monitor. There is no reasonable way to predict which undo segment or undo page will be used for any given transaction, there's no way to see what pages currently exist (or the contents of them) and there is no direct way to influence their destruction. Restarting the server will free the pages for internal re-use, but will leave their contents in place, unfortunately.

Is the Cassandra commit log just a backup of the (in memory) heap

I am new to cassandra and now I am trying to make a production server.
In documentation I read that data and commitlog should be on separated drives (btw I use hdd),
I tought the commitlog will increase to many Gb of data and I created 2 hard drives (both 100Gb), on first will be data (sstables) on second commitlog. But now in config I see:
commitlog_total_space_in_mb: 4096, and I think this shoul be 'the maximum heap size'. If commitlog reached this limit, then it seems that memtables increased in size and needs to be flushed to disk and also the data that was contained in memtables is removed from commitlog.
So tell me please if am I right: commitlog is like a backup of heap and cannot increase to hundreds of Gb?
And I do not need to create 100Gb hard drive for that, will be enough a 4Gb partition (on another hard drive, not the same where the data (sstables) is stored)?
commitlog is like a backup of heap and cannot increase to hundreds of Gb?
The commitlog is temporary storage used for a copy of data stored in the memtables. This is in case power is lost or the server otherwise crashes before the memtables can be written out as SSTables. As soon as a memtable is flushed to disk, the commitlog segments are deleted.
The rest of the data on heap (caches, in-flight data, etc.) is never stored in a commitlog. So your commitlog will normally be significantly smaller than your heap.
And I do not need to create 100Gb hard drive for that, will be enough a 4Gb partition (on another hard drive, not the same where the data (sstables) is stored) ?
A smaller partition will be fine, but you may want to leave a little headroom above 4 GB.

Why we should not have the collective size of innodb_log_files more than the size of the innodb_buffer_pool

Below is my understanding about the log file group.
Whenever innodb tables were inserted/updated those will be captured in innodb_log_buffer_size.
If the innodb_log_buffer_size filled up or time has come to flush it to the disc, they will be written onto innodb_log_files which are maintained in a group and committed in the table space at the same time.
Now my question is that why we should not have the collective size of innodb_log_files more than the size of the innodb_buffer_pool and why should we write to these log files though we are flushing it to the disc...?
I couldnt able to get proper explanation on this over the web at least I could not able to understand. Please give me some better explanation.
Really thanks in advance.
Regards,
UDAY
Now my question is that why we should not have the collective size of innodb_log_files more than the size of the innodb_buffer_pool and why should we write to these log files though we are flushing it to the disc...?
--> I am not sure where it is mentioned like innodb_buffer_pool_size should always be more than this value innodb_log_files_in_group * innodb_log_file_size.
Ofcourse! recommended size for innodb_buffer_pool_size should be 70-80% of available memory for Innodb-only installations, should be larger than default which is 8MB.
innodb_log_buffer_size a large log buffer enables large transactions to run without a need to write the log to disk before the transactions commit. Thus, if you have big transactions, making the log buffer larger saves disk I/O.
innodb_log_file_size The larger the value, the less checkpoint flush activity is needed in the buffer pool, saving disk I/O. But larger log files also mean that recovery is slower in case of a crash.
You should watch the Innodb_os_log_written variable over a period of several minutes, and estimate how many bytes per second are written to your InnoDB transaction logs. You can multiply this value by 3600 (an hour) and divide by innodb_log_files_in_group to choose a good log file size.
innodb_log_buffer_size uses internally to log to these log files in order to save Disc I/O.

file Autogrowth settings switched

What could be the impacts to change the default values for Autogrowth for the files of a database?
Actually I have a database with the Autogrowth values switched between the Data and Log files.
I have those values in those database properties:
DB_Data (Rows Data), PRIMARY, 71027 (Initial Size(MB)), "By 10 percent, unrestricted growth"
DB_Log (Log), Not Applicable, 5011, "By 1MB, restricted growth to 2097152 MB".
For the data file it depends whether or not you have instant file initialisation enabled for the SQL Server account. If you don't you should definitely consider using a fixed growth increment as the length of time that the file growth takes will grow exponentially in proportion to the size of the growth. If you grow the file in too small an increment then you can end up with file system fragmentation.
For the log file you should definitely consider a much larger number than 1MB as you will end up with VLF fragmentation. Log file growth cannot take advantage of instant file initialisation so should always use a fixed increment (say between 1GB - 4GB unless you know for a fact that the log will always remain small) .
Of course in an ideal world it wouldn't actually matter what you set these too as you should be pre-sizing files in advance at low traffic times rather than leaving when it happens to chance.