Make sure you know how much disk space you actually have
If youâre getting a disk full error when running a query, one thing for certain has happenedâwhile running the query, one or more nodes in your cluster ran out of disk space. This could be because the query is using a ton of memory and spilling to disk or because the query is fine and you just have too much data for the clusterâs hard disks. You can figure out which is the case by seeing how much space your tables are using by querying the stv_partitions table. I like to use this query from FlyData.select
sum(capacity)/1024 as capacity_gbytes,
sum(used)/1024 as used_gbytes,
(sum(capacity) - sum(used))/1024 as free_gbytes
from
stv_partitions where part_begin=0;
Ideally, you wonât be using more than 70% of your capacity. Redshift should continuing working well even when over 80% of capacity, but it could still be causing your problem. If it looks like you have plenty of space, continue to the next section, but if youâre using more than 90%, you definitely need to jump down to the âEncodingâ section.
Join at your own risk
If the query thatâs failing has a join clause, thereâs a good chance thatâs whatâs causing your errors. When Redshift executes a join, it has a few strategies for connecting rows from different tables together. By default, it performs a âhash joinâ by creating hashes of the join key in each table, and then it distributes them to each other node in the cluster. That means each node will have to store hashes for every row of the table. When joining large tables, this quickly fills up disk space. However, if the two join keys for the query are on the same node, the whole query can happen in place without using any additional memory. By setting up the tables so their dist keys are the same, you may be able to avoid a disk full error. When setting up dist keys, though, be wary of skew, which is discussed in the next section. If you canât change the dist key because the dist key is optimized for another query, the new key would cause skew issues, or some other reason, you may be able to make some changes to your query so it can still be executed. Here are some options you can try:-
- Use a subquery instead of a join. Some queries that use joins only need data from one of the tables but are using the join to verify some piece of information. In those cases, the join can often be replaced by an IN clause and a subquery. For example, a common query for us is to get some piece of information about users with subscriptions. Instead of joining the two tables, we can select users whose ids are in the subscriptions table. While holding on to the result of the subquery takes some memory, it is usually much less than whatâs needed for a hash join.
- Create and join subtables. In many cases, we are only retrieving small subsets of data from the tables being joined but are doing a hash join of whole tables. In those cases, you can create a table, usually a temporary one, that is a subset of a table being joined but has whatever filtering you need already applied. That way, by joining two small tables, the hashes are much smaller. You may even be able to distribute them so that there is no hash join at all. Again, this option uses some memory, but itâs much less than a hash join of the full tables.
