Some points I didn't see in other answers so far:
- A high end server SSD will ge bood for about 30.000 IO. RealSSD go up to 50.000
- As such, you CAN use RAID 5. Point. Your bottleneck is very likely going to be the RAID controller which simply is not made with SSD IOPS in mind, so it will max out it's CPU.
In general, SSD are about 100 times as fast as SAS drives in random IO. Some more. Depending on your requirements it is totally feasible to replace a RAID 10 of SAS with a RAID 5 of SSD and still get ahead - significnatly - both in IOPS as well as price.
Optimal stripe size is typical multiple of 64k - especially as SSD read / write in these segments anyway. TRIM is not necessarily needed then (no partial writes)... but it would be really nice to have that.
MS has some papars on SSD in databases which apply to oracle as well (same principle - optimizion IOPS). Oracle should have some, too.
If for whatever reason you prefer to try to clear those bad sectors, and you do not care about the existing contents of a drive, the below shell snippet may help. I tested this on an older Seagate Barracuda drive that is well past its warranty anyway. It might not work right with other drive models or manufacturers, but it should put you on the right path if you must script something. It will destroy any content you have on the drive.
You may prefer just running badblocks, an hdparm Secure Erase (SE) (https://wiki.archlinux.org/index.php/Securely_wipe_disk), or some other tool that is actually designed for this. Or even the manufacturer provided tools like SeaTools (there is a 32bit linux 'enterprise' version, google it).
Make sure the drive in question is completely unused/unmounted before doing this. Also, I know, while loop, no excuses. It is a hack, you can make it better...
baddrive=/dev/sdb
badsect=1
while true; do
echo Testing from LBA $badsect
smartctl -t select,${badsect}-max ${baddrive} 2>&1 >> /dev/null
echo "Waiting for test to stop (each dot is 5 sec)"
while [ "$(smartctl -l selective ${baddrive} | awk '/^ *1/{print substr($4,1,9)}')" != "Completed" ]; do
echo -n .
sleep 5
done
echo
badsect=$(smartctl -l selective ${baddrive} | awk '/# 1 Selective offline Completed: read failure/ {print $10}')
[ $badsect = "-" ] && exit 0
echo Attempting to fix sector $badsect on $baddrive
hdparm --repair-sector ${badsect} --yes-i-know-what-i-am-doing $baddrive
echo Continuning test
done
One advantage of using the 'selftest' method is the load is handled by the drive firmware, so the PC it is connected to is not loaded down like it would be with dd or badblocks.
NOTE : I'm sorry, I made a mistake, the correct while condition is like this :
while [ "$(smartctl -l selective ${baddrive} | awk '/^ *1/{print $4}')" = "Self_test_in_progess" ]; do
And the exit condition of the script becomes :
[ $badsect = "-" ] || [ "$badsect" = "" ] && exit 0
Best Answer
Your SSD is SATA so something has to do translation of SCSI commands for it. If you want to send raw commands you should use the set native to the device/controller unless you going to use "ATA Command Pass-Through" - i.e. you have a SCSI device behind a SATA controller but this is not the case here.
Linux's libata knows how to remap some but not all SCSI commands to ATA (see https://github.com/torvalds/linux/blob/e40dc66220b7ff1b816311b135b9298f8ba14ce6/drivers/ata/libata-scsi.c#L4222 ). According to https://events.static.linuxfound.org/sites/events/files/slides/discard_0.pdf the semantics of SCSI's UNMAP don't map well to ATA so it's unlikely that mapping will ever be implemented. However, notice that sending SCSI WRITE SAME with the unmap bit set to libata is translated to ATA TRIM so you could attempt to use that.
TLDR; SCSI UNMAP is not translated by libata. If you want to be protocol agnostic and have Linux do a block layer conversion for you then send a
BLKDISCARD
(e.g. via theblkdiscard
utility).